2010-03-22 4 views
0

데이터베이스의 테이블을 기반으로 일부 업데이트 문을 생성해야합니다. 내가 필요한 업데이트 문을 생성하는 다음 스크립트를 만들었습니다. 그러나 그 스크립트를 실행하려고 할 때 내용물의 이스케이프 처리되지 않은 작은 따옴표에 관한 오류가 발생하며 oracle에서 특별한 의미를 갖는 & B, & T 문자가 발생합니다. SET DEFINE을 OFF로 설정하여 & B와 & T 문제를 처리했습니다. 콘텐츠 내에서 작은 따옴표를 이스케이프하는 가장 좋은 방법은 무엇입니까?Oracle 10g - 작은 따옴표를 이스케이프 처리하는 가장 좋은 방법

DECLARE 
    CURSOR C1 IS 
     SELECT * FROM EMPLOYEES; 

BEGIN 
    FOR I IN C1 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('UPDATE EMPLOYEES SET 
      FIRST_NAME= ''' || I.FIRST_NAME|| ''', 
      LAST_NAME = ''' || I.LAST_NAME ''', 
      DOB = ''' || I.DOB|| ''' 
      WHERE EMPLOYEE_ID = ''' || I.EMPLOYEE_ID || ''';'); 
    END LOOP; 
END;     

여기서 first_name 또는 last_name에 작은 따옴표가 포함되어 있으면 생성 된 업데이트 문이 중단됩니다. first_name과 last_name에서 작은 따옴표를 이스케이프하는 가장 좋은 방법은 무엇입니까?

답변

1

당신은 REPLACE 사용할 수 있습니다

DECLARE 
    CURSOR C1 IS 
     SELECT * FROM EMPLOYEES; 

BEGIN 
    FOR I IN C1 
    LOOP 
     DBMS_OUTPUT.PUT_LINE('UPDATE EMPLOYEES SET 
      FIRST_NAME= ''' || REPLACE(I.FIRST_NAME,'''','''''') || ''', 
      LAST_NAME = ''' || REPLACE(I.LAST_NAME,'''','''''') || ''', 
      DOB = TO_DATE(''' || TO_CHAR(I.DOB,'DD/MM/YYYY') || '',''DD/MM/YYYY'')' 
      WHERE EMPLOYEE_ID = ' || I.EMPLOYEE_ID || ';'); 
    END LOOP; 
END; 

참고 : 당신은 I.LAST_NAME|| 누락 된

  • .
  • I.EMPLOYEE_ID은 숫자라고 가정합니다.이 경우 따옴표로 묶지 않습니다.
  • 나는 I.DOB이 날짜라고 가정합니다.이 경우 명시 적으로 날짜로 캐스팅하는 것이 좋습니다.

대안 :는 당신이 이상 오라클 10g에 있다면, 당신은 쉽게 읽을 수 있습니다이 다른 구문을 사용할 수 있습니다; - 그리고 무슨 일이 일어나고 있는지가 좀 더 분명하게 REPLACE를 사용 이건 내 개인적인 취향 :

DECLARE 
    CURSOR C1 IS 
     SELECT * FROM EMPLOYEES; 

BEGIN 
    FOR I IN C1 
    LOOP 
     DBMS_OUTPUT.PUT_LINE(REPLACE(REPLACE(REPLACE(REPLACE(
     q'[UPDATE EMPLOYEES SET 
      FIRST_NAME= q'{#FIRST_NAME#}', 
      LAST_NAME = q'{#LAST_NAME#}', 
      DOB = DATE '#DOB#' 
      WHERE EMPLOYEE_ID = #EMPLOYEE_ID#; 
      ]' 
      ,'#FIRST_NAME#', I.FIRST_NAME) 
      ,'#LAST_NAME#', I.LAST_NAME) 
      ,'#DOB#', TO_CHAR(I.DOB,'YYYY-MM-DD')) 
      ,'#EMPLOYEE_ID#', I.EMPLOYEE_ID) 
      ); 
    END LOOP; 
END; 

위가에서 선택하지 동적 SQL에서 가능한 오류를 발견하기 쉬운 장점이있다 구문 오류에 대한 컴파일 시간.

+0

@ 제프리 : 의견에 감사드립니다. 이 접근법의 유일한 단점은 NULL 값의 경우, first_name이 REPLACE (I.FIRST_NAME, '' ',' '' '' ')를 사용하여 테이블에서 NULL이 발생했다는 것을 의미합니다. 빈 문자열을 테이블에 삽입하는 것은 NULL과 같지 않다고 생각합니다. 그렇지 않니? 현재로서는 좀더 자세한 정보를 IF ... ELSE 검사를 NULL로 사용했는데 그렇지 않은 경우 q '(I.first_name)'등을 사용했습니다. 그 일. 다시 한 번 의견에 감사드립니다. – Dharam

+0

아니요. Oracle에서 빈 문자열은 NULL과 같습니다. –

+0

Q- 따옴표로 대체하는 방법이 불완전합니다. 단일 인용 부호는 생성 된 갱신 명령문에서 이스케이프 처리되지 않은 상태로 남아 있습니다. 다른 구분 기호로 _and_뿐만 아니라 텍스트 열을 래핑하려면 Q- 따옴표를 사용해야합니다. 예. '# FIRST_NAME #' '은 (는)'q {'# FIRST_NAME # '}'이어야합니다. –

관련 문제