2017-02-08 13 views
1

以下のように、別の表に記載されている一連のルールを満たしている場合は、ファイルのすべてのレコードのレコードを読み込んで別のファイルに挿入する必要があります。 。動的にSQLステートメントを準備するロジック

enter image description here

記録、それは最初のファイルから読み込まれた後の第二のテーブルに書き込むことが適格にするために少なくとも1つのルールの順序をすべて満たさなければなりません。

例えば、レコードがCARファイルから読み込まれると、以下のルールは、少なくとも1つのルールセットのすべてのシーケンスが満たされるまでチェックされなければなりません。このため、私はこの種の動的SQLプログラムを作成する予定でした。 Prepared SQLはホスト変数をサポートしていないため、これは機能しません。

enter image description here

すべてのボディが示唆またはSQL statemtns動的に作成し、それを第二のファイルに入力するためのレコードが必要なルールを満たすかどうかを確認する方法上の任意のガイダンスを提供できる場合

、それは素晴らしいことだ

基本的に私が探しているのは、テーブルからフィールドを選択した後で、それをさらに保存して検証とチェックを行う方法です。

更新

Danny117からインテリジェントなアドバイスをもとに、私は以下のコードが出ている:

H Option(*NoDebugIO:*SrcStmt)          
D RULEDS  E DS     EXTNAME(RULESTABLE)   
D MAXRUL   S    1 0        
D MAXSEQ   S    1 0        
D STMT   S   512        
D WHERESTMT  S   512 INZ('')      
D FullSqlStmt  S   512 INZ('')      
D RULINDEX  S    1 0 INZ(1)      
D SEQINDEX  S    1 0 INZ(1)      
D APOS   C     CONST('''')     
    /Free               
    Exec SQL SELECT MAX(RULENO)INTO :MAXRUL FROM RULESTABLE;  
    Exec SQL DECLARE RULCRS CURSOR FOR SELECT * FROM RULESTABLE; 
    Exec SQL OPEN RULCRS;           
    Exec SQL FETCH RULCRS INTO :RULEDS;       
    DoW (Sqlcod = 0 AND RULINDEX <= MAXRUL);      
     Exec SQL SELECT MAX(SEQNO) INTO :MAXSEQ FROM RULESTABLE  
     WHERE RULENO=:RULINDEX ;         
     DoW (SEQINDEX <= MAXSEQ);         
    If (Position <> '');          
    Field = 'SUBSTR('+%Trim(Field)+','+%Trim(Position)+',' 
    +'1'+')';            
    EndIf;             
    WhereStmt = %Trim(WhereStmt) + ' ' + %Trim(field)+ ' ' + 
    %Trim(condition) + ' ' + APOS + %Trim(Value) + APOS;  

    If (SeqIndex < MaxSeq);         
    WhereStmt = %Trim(WhereStmt) + ' AND ';     
    EndIf;             


    Exec SQL FETCH NEXT FROM RULCRS INTO :RULEDS;    
    SeqIndex = SeqIndex + 1;         
EndDo;              
FullSqlStmt = %Trim('INSERT INTO ITMRVAT SELECT * +   
FROM ITMRVA WHERE '+ %Trim(WhereStmt));      
Exec SQL Prepare InsertStmt from :FullSqlStmt;    
Exec SQL EXECUTE InsertStmt;        
    RulIndex = RulIndex + 1; 
EndDo; 

その下に示すように、これは、SQL文を生成し私が欲しいものです。さあ、コードの他の部分を見てみましょう。

> EVAL FullSqlStmt              
    FULLSQLSTMT =               
      ....5...10...15...20...25...30...35...40...45...50...55...60 
     1 'INSERT INTO ITMRVAT SELECT * FROM ITMRVA WHERE STID = 'PLD' ' 
     61 'AND ENGNO LIKE '%415015%' AND SUBSTR(ENGNO,1,1) = 'R' AND SU' 
    121 'BSTR(ENGNO,5,1) = 'Y'          ' 
    181 '               ' 
    241 '               ' 
    301 '               ' 
    361 '               ' 
    421 '               ' 
    481 '        '        

しかし、私はダニーに私のコメントで述べたような問題が第二のテーブルを含む新しいルールが指定されている場合はどのように処理するか、今..です

+0

どのような意味ですか:[タグ:c]のようなプログラミング言語を使用して、スクリプトを使用しています.... – LPs

+0

私は埋め込みSQLRPGプログラムを作成しようとしています。 RPGは、IBM iプラットフォームで使用される主な言語です。しかし、私は疑問がDB2上にあるので、これは問題ではないと思う。 –

+0

ルールで参照される第2のテーブルをどのように扱うべきかについて私たちが言うことは不可能である。 2番目のテーブルが参照されたときの結果を含むサンプルを表示して、それが明らかになるかもしれません。 – user2338816

答えて

0

ルールをjoin文またはwhere句に変換する必要があります。 joinステートメントはより複雑なので、そのルートに進みます。

スマートであれば、ルールをwhere句に参加または使用できるSQL句として保存することを検討してください。この方法は無限に柔軟性があり、よりモダンなデザインです。

ルール1/car.year = 1990とcar.engnoのように '%43243%'と部分文字列(car。VIN、12,1)= 'X'

eval statement = 
insert into sometable 
Select car.* from car 
join sysibm.sysdummy1 
on car.year = 1990 
and car.engno lile '%43243%' 

...などの始まる2を支配する "OR"

or car.year = PLD 
and car.engno like '%1234%' 

へ...と "OR"

始まるなど、他のルール
exec immediate statement 
+0

これは正しいアプローチであるようです。私は先に進み、 –

+0

を参照してください。これは、RULEテーブルに1つのテーブルのみを含めると理想的なアプローチです。すなわちCAR。しかし、ユーザーがルールセットのシーケンスの1つとしてFILE = CAR_LOCATION、FIELD = CITY、CONDITION = '='、VALUE = 'IOMA'のような別のテーブルに基づいてルールを入力したとします。それは特定の場所にある車の詳細だけを挿入したいビジネスです。これには、CARテーブルとLOCATIONテーブルをリンクするフィールドの知識が必要です。私は正しい?あなたの考えを分かち合いましょう –

+0

それはあなたの企業のすべてのテーブルには当てはまりません。 NoSQLがどこかにSQLがあります。それは、摩擦が加速に対してどのように作用し、物体を動かすかを過ぎて、量子物理学のようなものです。 – danny117

3

Embedded SQLはILEの「動的ステートメント」も認めていません言語。文字フィールド内でクエリを実行し、Embedded SQLに渡すことができます。

Dcl-S lQuery Varchar(100); 

lQuery = 'SELECT * FROM CUST'; 

EXEC SQL 
    PREPARE SCust FROM :lQuery; 
EXEC SQL 
    DECLARE SearchCust CURSOR FOR SCust; 

//Continue working with cursor.. 

あなただけの結果セットを、準備し、実行して返すようにしたいことがあります。

lQuery = 'SELECT * FROM CUST WHERE ID = ' + %Char(CustID); 

EXEC SQL 
    PREPARE SCust FROM :lQuery; 

DECLARE c1 CURSOR FOR SCust; 
OPEN c1; 
FETCH c1 INTO :CustDS; 
CLOSE c1; 

オプションの余分:(?)あなたは、あなたのクエリでフィールドマーカーを使用することをお勧めします。

//'SELECT * FROM CUST WHERE CUSTID = ?'; 
EXEC SQL OPEN SearchCust USING :CustID; 

//'INSERT INTO CUST VALUES(?,?)'; 
EXEC SQL EXECUTE CUST USING :CustID; 
+1

私はこれらすべてを知っています。しかし、私が今しようとしているのは、STMT = 'SELECT' +%TRIM(FIELD)+ 'INTO:STID FROM' +%TRIM(FILE)+ 'WHERE RRN(ITMRVA)= 1'です。 EXEC SQLプリペアSQLSTMT FROM:STMT;おそらくSELECT INTOが使用されているため、SQLCOD -312で失敗する可能性があります。このような声明をどのように準備するのですか? –

+0

@ user3311539クエリからINTOを削除し、上記の例を使用してクエリを準備し、INTO句を使用して準備された文を実行します。私はあなたにあなたの答えを更新します。 –

+0

私はCUSTDSがEXTNAME(CUST)として定義された外部データ構造であると推測します。したがって、1つの変数を選択している場合、これは機能するはずです。EXEC SQL EXECUTE SQLSTMT INTO:STID;しかし、これはうまく動作せず、エラーはトークンです:有効ではありませんでした。有効なトークン:SQL DESCRIPTOR。 –

関連する問題