2017-07-19 15 views
-1

まず、私の悪い英語について謝罪したいと思います。複数の検索条件にカーソルを使用する

とにかく。私はいくつかのレコードを表示するサブファイルを持つディスプレイファイルを開発しています。これは、1つの選択を表示するときの魅力のように動作しますが、今はユーザーのための検索機能を開発したいと思います。したがって、ユーザーが異なる検索条件を入力すると、選択が変更され、カーソルは何らかの形で新しい選択で更新されなければなりません。私は私の髪をリッピングしている、私は本当にこれを動作させることはできません。

"mcpressonine" -forumの投稿を見つけました。私とまったく同じ問題を抱えていて、何とかこれを解決してくれる人がいますが、彼が何をしたのかは分かりません。私がやった副手続き - 成功なし。誰かが彼が何をしたかを説明している場合、私は非常に感謝するでしょう His post

:ここ

は、彼のフォーラムの投稿へのリンクです。彼の投稿が10歳になってから、この男のソリューションはもはや有効ではないかもしれない。 情報が不十分で、途中で修正するかどうか教えてください。

ありがとうございます! 種類Jesper

+0

あなたのコードや、あなたがやろうとしていることのいくつかの例を示します。実行の間にステートメントをどのように変更したいのですか?どのようなエラーメッセージが表示されますか? – Charles

+0

ポストは、ただちにSQL文を作成します。その後、それを実行します。 order by節がすぐに変化しているのが分かります。 – danny117

答えて

0

カーソルは、埋め込みSQLプログラムまたはストアドプロシージャで1回だけ宣言できます。また、複数のカーソルを宣言することもできます。しかし、そのカーソルにリンクされたSQLステートメントは、時間の経過とともに変化する可能性があります。

参考文献のアドバイスは有効です。 (ストアド・プロシージャのように)カーソルを1回宣言することはできますが、カーソルが最初にクローズされている限り(オープンされていた場合)、新しいSQL-

+0

OPが実際に動的SQLを必要とするかどうかは分かりません。何が変更されているかによって、静的が機能することがあります。 – Charles

1

などのステートメントが正常に準備され、カーソルが、その後再度オープン心に留めておくべき事はDECLARE文が実行可能ではないということです。これはコンパイル時の宣言です。 PREPAREおよびOPENが実行可能です。

以下は、動的SQLを使用する完全に機能するプログラムです。DeclareCursorサブルーチンが実際に呼び出されることはありません。重要なのは、PREPAREステートメントが実行されたときのgSqlStmtのステートメントです。

**FREE 
ctl-opt main(mymain); 
ctl-opt option(*srcstmt); 

dcl-c QUOTE const(''''); 

dcl-s gSqlStmt varchar(500); 

dcl-proc MyMain; 
    dcl-s company char(3); 
    dcl-s part char(25); 
    dcl-s desc char(30); 
    dcl-s msg  char(50); 
    dcl-s selComp char(3); 

    selComp = 'A06'; 
    gSqlStmt = 'select pmco#, pmpart, pmdesc' 
      + ' from pdpmast' 
      + ' where pmco# = ' + QUOTE + selComp + QUOTE; 

    exsr OpenCursor; 
    exsr FetchData; 
    exec SQL close C1; 

    selComp = 'A15'; 
    gSqlStmt = 'select pmco#, pmpart, pmdesc' 
      + ' from pdpmast' 
      + ' where pmco# = ' + QUOTE + selComp + QUOTE; 
    exsr OpenCursor; 
    exsr FetchData; 
    exec SQL close C1; 

    *INLR = *ON; 
    return; 

    begsr DeclareCursor; 
    exec SQL 
     declare C1 cursor for S1; 
    endsr; 

    begsr OpenCursor; 
    exec SQL prepare S1 from :gSqlStmt; 
    exec SQL open C1; 
    endsr; 

    begsr FetchData; 
    exec sql fetch next from C1 into :company, :part, :desc; 
    msg = company + ':' + part + ':' + %subst(desc:1:20); 
    dsply msg; 
    endsr; 
end-proc; 

任意のエラー処理を持っていないまた、上記直接ステートメントに、入力変数、selCompを連結するの悪い習慣を含有します。 SQLインジェクション攻撃のため、これはどの言語でも良い考えではありません。

パラメータマーカーを使用するより優れたバージョンは以下のとおりです。ステートメントはもう変更する必要はありません。だから私はそれを一度しか準備する必要はありません。レコードの選択は、OPEN ... USING...ステートメントが呼び出された時点のselCompの値によって決まります。

**FREE 
ctl-opt main(mymain); 
ctl-opt option(*srcstmt); 

dcl-s gSqlStmt varchar(500); 

dcl-proc MyMain; 
    dcl-s company char(3); 
    dcl-s part char(25); 
    dcl-s desc char(30); 
    dcl-s msg  char(50); 
    dcl-s selComp char(3); 

    gSqlStmt = 'select pmco#, pmpart, pmdesc' 
      + ' from pdpmast' 
      + ' where pmco# = ?'; 
    exec SQL prepare S1 from :gSqlStmt; 

    selComp = 'A06'; 
    exsr OpenCursor; 
    exsr FetchData; 
    exec SQL close C1; 

    selComp = 'A15'; 
    exsr OpenCursor; 
    exsr FetchData; 
    exec SQL close C1; 

    *INLR = *ON; 
    return; 

    begsr DeclareCursor; 
    exec SQL 
     declare C1 cursor for S1; 
    endsr; 

    begsr OpenCursor; 
    exec SQL open C1 using :selComp; 
    endsr; 

    begsr FetchData; 
    exec sql fetch next from C1 into :company, :part, :desc; 
    msg = company + ':' + part + ':' + desc; 
    dsply msg; 
    endsr; 
end-proc; 

ただし、ここでは動的SQLは実際には必要ありません。ホスト変数を持つ静的なステートメントは正常に動作します。静的SQLでは、は必要ありません。また、OPENにはselCompを指定する必要はありません。コンパイル時に自動的に行われます。

**FREE 
ctl-opt main(mymain); 
ctl-opt option(*srcstmt); 

dcl-s gSqlStmt varchar(500); 

dcl-proc MyMain; 
    dcl-s company char(3); 
    dcl-s part char(25); 
    dcl-s desc char(30); 
    dcl-s msg  char(50); 
    dcl-s selComp char(3); 

    selComp = 'A06'; 
    exsr OpenCursor; 
    exsr FetchData; 
    exec SQL close C1; 

    selComp = 'A15'; 
    exsr OpenCursor; 
    exsr FetchData; 
    exec SQL close C1; 

    *INLR = *ON; 
    return; 

    begsr DeclareCursor; 
    exec SQL 
     declare C1 cursor for 
      select pmco#, pmpart, pmdesc 
      from pdpmast 
      where pmco# = :selComp; 
    endsr; 

    begsr OpenCursor; 
    exec SQL open C1; 
    endsr; 

    begsr FetchData; 
    exec sql fetch next from C1 into :company, :part, :desc; 
    msg = company + ':' + part + ':' + desc; 
    dsply msg; 
    endsr; 
end-proc; 
関連する問題