我必须根据数据库中的表生成一些更新语句。我创建了以下脚本,它生成了我需要的更新语句。但是当我尝试运行这些脚本时,我收到的错误与内容中未转义的单引号以及在oracle中具有特殊含义的& B,& T字符有关。我通过将SET DEFINE设置为OFF来处理& B和& T问题。什么是逃避内容中单引号的最佳方式?
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包含单引号,则生成的update语句会中断。什么是逃避first_name和last_name中单引号的最佳方法?
答案 0 :(得分: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
是一个日期 - 在这种情况下,我建议您明确地将其投放到某个日期。 <强> ALTERNATIVE:强>
如果您使用的是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中可能存在的错误,在编译时没有检查语法错误。