2010-03-22 27 views
0

我必須根據數據庫中的表生成一些更新語句。我創建了以下腳本,它生成我需要的更新語句。但是當我嘗試運行這些腳本時,我收到了有關內容中未轉義的單引號以及oracle中具有特殊含義的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是一個日期 - 在這種情況下,我建議您明確地將其轉換爲日期。

替代方案: 如果你在Oracle 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碰巧在表中爲NULL,使用REPLACE(I.FIRST_NAME,'''',''''''),我們在表中插入空字符串,我認爲它不是NULL。不是嗎?現在即使它更詳細,我已經使用IF..ELSE檢查NULL,如果沒有,我使用q'(I.first_name),等等。它的工作。再次感謝您的反饋。 – Dharam 2010-03-23 03:34:41

+0

否。在Oracle中,空字符串與NULL相同。 – 2010-03-23 08:00:43

+0

帶Q-引號的替代方法不完整。單引號將在生成的更新語句中保持未轉義狀態。您將需要使用Q-quotes來包裝文本列以及使用不同的分隔符。例如。 '#FIRST_NAME#''應該是'q {'#FIRST_NAME#'}' – 2016-07-14 00:42:59