2017-02-08 4 views
1

아래 나와있는 다른 표에 설명 된 규칙 집합을 충족 시키려면 파일의 모든 레코드 레코드를 읽고 다른 파일에 삽입해야하는 요구 사항이 있습니다. .동적으로 SQL 문을 준비하는 논리

enter image description here

이 첫 번째 파일에서 읽은 후 레코드는 두 번째 테이블에 기록하는 것을받을 수 있도록 하나 이상의 규칙의 모든 시퀀스를 충족해야한다.

예를 들어 CAR 파일에서 레코드를 읽은 후에는 적어도 하나 이상의 규칙 집합의 모든 시퀀스가 ​​충족 될 때까지 아래의 규칙을 확인해야합니다. 이를 위해 나는 이런 종류의 동적 SQL 프로그램을 만들 계획을 세웠다. 그러나 Prepared SQL은 호스트 변수를 지원하지 않으므로이 기능은 작동하지 않습니다.

enter image description here

어떤 몸이 제안 또는 SQL statemtns 동적를 생성하고이 두 번째 파일에 입력하는 레코드가 필요한 규칙을 만족하는지 확인하는 방법에 대한 지침을 제공 할 수있는 경우

, 그것은 좋은 것

그래서 기본적으로 내가 찾고있는 것은 테이블에서 필드를 선택하면 추가 확인 및 검사를 수행하기 위해 어딘가에 저장하는 방법입니다. 이는 아래와 같이

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 문을 생성합니다

업데이트

: Danny117에서 지능형 조언을 바탕으로

, 나는 아래의 코드로 올라와있다 내가 원하는거야. 이제 코드의 다른 부분을 살펴 보겠습니다.

> 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

동적으로 의미 : 스크립팅을 사용하여 [tag : c]와 같은 프로그래밍 언어 사용. – LPs

+0

Embedded SQLRPG 프로그램을 작성하려고합니다. RPG는 IBM i 플랫폼에서 사용되는 주요 언어입니다. 하지만 의심의 여지가 DB2에 관한 것이므로이 점은 중요하지 않다고 생각합니다. –

+0

규칙에서 언급 된 두 번째 테이블을 처리하는 방법을 말할 수 없습니다. 두 번째 테이블을 참조 할 때 결과를 포함하는 예제를 보여 주면 명확해질 수 있습니다. – user2338816

답변

0

규칙을 조인 문 또는 where 절로 변환해야합니다. 조인 문은 더 복잡하므로 해당 경로로 이동하십시오.

똑똑한 사람이라면 where 규칙에 참여하거나 사용할 수있는 SQL 절로 규칙을 저장하는 것이 좋습니다. 그것의 무한히 유연한 방법은 더 현대적인 디자인입니다.

규칙 1/car.year = 1990 및 car.engno처럼 '% 43243 %'및 하위 문자열 (자동차.자동차 등록, 등등에 12,1) = 'X'

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

은 ...

로 시작하는이 규칙 "OR"

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

... 등 다른 규칙으로 시작 "OR"로

exec immediate statement 
+0

이것은 여기에 올바른 접근 방법 인 것 같습니다. 나는 이것을 계속하고 –

+0

을 볼 것입니다. 이것은 RULE 테이블이 하나의 테이블 만 포함하는 경우에 이상적인 접근 방법 인 것 같습니다. 즉 CAR. 그러나 사용자가 FILE = CAR_LOCATION, FIELD = CITY, CONDITION = '='및 VALUE = 'IOMA'와 같이 다른 테이블을 기반으로 규칙을 입력하면 규칙 집합의 시퀀스 중 하나라고 가정합니다. 특정 위치에있는 자동차 세부 정보 만 삽입하려는 비즈니스입니다. CAR 테이블과 LOCATION 테이블을 연결하는 필드에 대한 지식이 필요합니다. 내가 맞습니까? 생각을 나누십시오. –

+0

아니요, 기업의 모든 테이블이 될 수는 없습니다. 그런 생각 수준에 도달해야합니다. NoSQL하지만 어딘가에 SQL이 있습니다. 그것은 마찰이 가속에 대해 작용하고 움직이는 물체를 유지하는 과거의 양자 물리학 방식과 같습니다. – danny117

3

임베디드 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 PREPARE SQLSTMT FROM : STMT; 이는 SELECT INTO가 사용 되었기 때문에 SQLCOD -312로 인해 실패했을 수 있습니다. 이런 진술을 어떻게 준비할까요? –

+0

@ user3311539 쿼리에서 INTO를 제거하고 위 예제를 사용하여 쿼리를 준비한 다음 준비된 문을 INTO 절로 EXECUTE합니다. 나는 당신에게 보여줄 나의 대답을 업데이트 할 것이다. –

+0

CUSTDS는 EXTNAME (CUST)으로 정의 된 외부 데이터 구조입니다. 따라서 하나의 변수 만 선택하면 다음과 같이 작동합니다. EXEC SQL EXECUTE SQLSTMT INTO : STID; 그러나이 doesnt 일 및 과실은 토큰이다 : 유효하지 않았다. 유효한 토큰 : SQL DESCRIPTOR. –