Kori 4월 20일, 2022에 포스트됨 공유하기 4월 20일, 2022에 포스트됨 Docwiki에 있는 "SQL Scripts Questions (FireDAC)"을 번역한 글: 번역일: 2022년 4월 18일 위로 가기: [DocWiki 번역] FAQ (FireDAC) SQL 스크립트 실행 관련 질문과 답변을 정리한 목록이다. Q1: 쿼리 끝에서 세미콜론(;)을 사용하지 못하는 이유는? 쿼리에서 이것을 제거했더니 작동한다. A: ';'는 많은 SQL 스크립트 사투리에서 SQL 명령(command)의 구분자(delimiter)일 뿐이고, SQL 언어가 아니다. 몇몇 DBMS에서는 SQL 명령(command)의 끝에 ';'을 허용하고, 어떤 것들은 허용하지 않는다. 다시 말하자면, 그냥 ';'를 제거하라. Q2: 몇몇 DBMS (PG, Oracle, FB)에서는 SQL 구문을 오직 하나만 실행할 수 있다. 하지만, SQLite 에서는 구문 여러 개를 한번에 실행할 수 있다. 왜 그런가? A: 그렇게 설계되어 있기 때문이다 – ExecSQL 메소드는 SQL 명령을 있는 그대로 DBMS API에게 전달한다. 만약 DBMS에서 "묶음(batch)" 쿼리를 지원한다면, 실행이 될 것이고, 그렇지 않다면 실패할 것이다. TFDScript를 사용하면 SQL 명령(command) 여러 개를 담은 SQL 스크립트들을 실행하고 명령을 제어할 수 있다. Q3: 스크립트가 1개 이상 있는데도, ExecuteAll는 오직 첫번째 스크립트만 실행한다. A: 첫번째 스크립트가 "근본(root)" 스크립트이다. 다른 스크립트들 실행하려면, "근본(root)" 스크립트에서 명시적으로 호출해야 한다. 예를 들면: with FDScript1.SQLScripts do begin with Add do begin Name := 'root'; SQL.Add('@first'); // 명시적으로 '첫번째' 스크립트 호출 SQL.Add('@second'); // 명시적으로 '두번째' 스크립트 호출 end; with Add do begin Name := 'first'; SQL.Add('create table t1 ...;'); SQL.Add('create table t2 ...;'); end; with Add do begin Name := 'second'; SQL.Add('create procedure p1 ...;'); SQL.Add('create procedure p2 ...;'); end; end; ExecuteStep은 TFDScript.Position 지점으로 부터 그 다음 스크립트 명령을 실행한다. ExecuteAll은 스크립트 전체를 실행한다. ValidateAll / ValidateStep 메소드도 있다. 이 메소드들은 스크립트를 진행하지만, SQL 스크립트를 실행하지는 않는다. ValidateAll을 호출하면 TFDScript.TotalJobSize에 값을 할당(assign)한다. 따라서 그 다음에 ExecuteAll을 호출하면 TFDScript.TotalPct10Done을 올바르게 업데이트 한다. 이것은 진행된 스크립트 명령의 10%에 해당된다. Q4: (1) 각 SQL 구문마다 FDConnection.ExecSQL 실행하기 (2) FDScript.ExecuteAll 실행하기는 성능 상 차이가 있는가? : A: 이 2개의 메소드 뒤에서 SQL을 실행하는 코드는 동일하다. 둘 다 IFDPhysCommand.Execute 메소드를 사용한다. TFDScript 파서(parser, 구문 분석기)는 고도로 최적화되어 있다. 이 파서는 Oracle PL/SQL (여기에서는 명령문 안에 ';'이 들어 있을 수 있다) 등 DBMS 마다 제각각인 많은 SQL 사투리를 인식하며 정밀하고 유연하게 제어한다. 따라서, 당신이 FDConnection.ExecSQL에 한번에 하나의 명령(command)을 제출한다면, 이런 명령들을 별도의 스크립트 하나로 뽑아 내거나 할 필요가 없다. FireDAC이 알아서 가장 빠른 방식을 사용할 것이다. 만약 SQL 스크립트가 파일 하나 안에 들어 있다면 FDScript.ExecuteAll이 가장 빠른 방식이다. Q5: 스크립드 작업이 실패했을 때 롤백(ollback)하는 방법은? A: 1) Use FireDAC 트랜젝션 제어를 사용한다: FDConnection1.StartTransaction; try FDScript1.ExecuteAll; FDConnection1.Commit; except FDConnection1.Rollback; raise; end; 2) Oracle인 경우 PL/SQL 블록을 사용하고, 다른 DBMS라면 이와 유사한 구조를 사용한다: begin insert into u_btk.t_test values (1, sysdate); insert into u_btk.t_test values (2, sysdate); insert into u_btk.t_test values (1, sysdate); commit; exception when others then rollback; raise; end; 3) TFDScript.OnError를 사용한다: procedure TForm1.FDScript1Error(ASender: TObject; const AInitiator: IFDStanObject; var AException: Exception); begin FDConnection1.Rollback; end; Q6: 아래 스크립트를 FB(파이어버드)에서 실행하면, “Unexpected end of command line 3” 에러가 난다. 어떻게 고치나? EXECUTE BLOCK AS DECLARE VARIABLE MYVAR VARCHAR(250); BEGIN ... END; A: block(블록)을 가진 SQL 스트립트를 실행하려면, block(블록) 앞에서 명령 구분자(command separator)를 변경해야 한다. 원한다면 블록 처리 뒤부터 다시 원래대로 돌려놓을 수도 있다. 예를 들면; SET TERM #; EXECUTE BLOCK ... END; # SET TERM ;# 인용하기 이 댓글 링크 다른 사이트에 공유하기 더 많은 공유 선택 사항
Recommended Posts
이 토의에 참여하세요
지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.