为什么手动 运行 SQL 阻止工作但在同一字符串上使用 EXECUTE IMMEDIATE 却不起作用?
Why does manually running SQL block work but using EXECUTE IMMEDIATE on the same string doesn't?
以下过程失败并出现 "ORA-0097: missing equal sign error"。
CREATE PROCEDURE AMEPSA.USP_ETL_BATCH_MASTER_UPDATE
(ENVIRONMENT in VARCHAR2, BATCH_STATUS in VARCHAR2, BATCH_USER_ID VARCHAR2, BATCH_JOB_NAME VARCHAR2)
AS
BEGIN
IF (BATCH_STATUS = 'Running') THEN
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_' || ENVIRONMENT || ' = ' || '''' || BATCH_STATUS || '''' || ',
BATCH_JOB_NAME_' || ENVIRONMENT || ' = ' || '''' || BATCH_JOB_NAME || '''' || ',' ||
'BATCH_USER_ID_' || ENVIRONMENT || ' = ' || '''' || BATCH_USER_ID || '''' || ',' ||
'BATCH_START_DATE_' || ENVIRONMENT || ' = TO_DATE(' || '''' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH24:MI:SS') || '''' || ', ' || '''' || 'MM/DD/YYYY HH24:MI:SS' || '''' || ') ' || ',' ||
'BATCH_END_DATE_' || ENVIRONMENT || ' = ' || 'NULL' || '
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)';
ELSE
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_' || ENVIRONMENT || ' = ' || '''' || BATCH_STATUS || '''' || ',
BATCH_JOB_NAME_' || ENVIRONMENT || ' = ' || '''' || BATCH_JOB_NAME || '''' || ',' ||
'BATCH_END_DATE_' || ENVIRONMENT || ' = ' || 'TO_DATE(' || '''' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH24:MI:SS') || '''' || ', ' || '''' || 'MM/DD/YYYY HH24:MI:SS' || '''' || ')
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)';
END IF;
COMMIT;
END;
GO
在调试问题时,我们用 DBMS_OUTPUT.PUT_LINE 语句替换了 EXECUTE IMMEDIATE 语句。这样做之后,该过程返回了一个字符串(如下),该字符串成功执行且没有语法错误。
UPDATE AMEPSA.ETL_BATCH_MASTER
SET BATCH_STATUS_STAGE = 'Running',
BATCH_JOB_NAME_STAGE = 'wf_TADM_Stage',
BATCH_END_DATE_STAGE = TO_DATE('08/14/2017 15:42:00', 'MM/DD/YYYY HH24:MI:SS')
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)
当从 DBMS_OUTPUT.PUT_LINE 语句返回的结果字符串在语法上正确时,为什么 EXECUTE IMMEDIATE 语句会认为它缺少等号?
来自 Informatica 的完全异常:
Severity: ERROR Timestamp: 8/15/2017 9:46:10 AM Node: didre2007
Thread: TRANSF_1_1_1 Process ID: 9072 Message Code: CMN_1022 Message:
Database driver error... CMN_1022 [ ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 14 ORA-06512:
at line 2
Database driver error... Function Name : ExecuteSP
Oracle Fatal Error Database driver error... Function Name : ExecuteSP
Oracle Fatal Error]
看起来传递给过程的参数值有单引号;特别是第一个,但可能是所有的。可以直接调用复制:
exec USP_ETL_BATCH_MASTER_UPDATE('''STAGE''', '''Running''', '''someuser''', '''wf_TADM_Stage''');
得到
Error report -
ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 14
ORA-06512: at line 1
00927. 00000 - "missing equal sign"
或者只是
exec USP_ETL_BATCH_MASTER_UPDATE('''STAGE''', 'Running', 'someuser', 'wf_TADM_Stage');
进入另一个分支并得到:
Error report -
ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 6
ORA-06512: at line 1
00927. 00000 - "missing equal sign"
通过调试显示代码在执行之前,您可以看到它最终尝试 运行 这个:
UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_'STAGE' = 'Running',
BATCH_JOB_NAME_'STAGE' = 'wf_TADM_Stage',BATCH_USER_ID_'STAGE' = 'someuser',BATCH_START_DATE_'STAGE' = TO_DATE('08/15/2017 19:37:00', 'MM/DD/YYYY HH24:MI:SS') ,BATCH_END_DATE_'STAGE' = NULL
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)
引用不当; BATCH_STATUS_'STAGE'
构造抛出异常。
如果在没有那些额外的单引号的情况下调用,您所展示的内容在任一分支中都有效。
因此,您需要调查为什么 Informatica 添加这些单引号——可能只是开发人员对如何将字符串作为参数处理感到困惑——并停止这样做。问题不在您显示的代码中,并且在没有看到 Informatica 代码的情况下,我无法更具体地说明应该如何修复它。
顺便说一句,在评论中提到您可以通过 using
子句使用绑定变量,而不是将 sysdate
转换为字符串并返回;这与您收到的错误无关,但可能看起来像:
CREATE PROCEDURE AMEPSA.USP_ETL_BATCH_MASTER_UPDATE
(ENVIRONMENT in VARCHAR2, BATCH_STATUS in VARCHAR2, BATCH_USER_ID VARCHAR2, BATCH_JOB_NAME VARCHAR2)
AS
BEGIN
IF (BATCH_STATUS = 'Running') THEN
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET'
|| ' BATCH_STATUS_' || ENVIRONMENT || ' = :BATCH_STATUS,'
|| ' BATCH_JOB_NAME_' || ENVIRONMENT || ' = :BATCH_JOB_NAME,'
|| ' BATCH_USER_ID_' || ENVIRONMENT || ' = :BATCH_USER_ID,'
|| ' BATCH_START_DATE_' || ENVIRONMENT || ' = SYSDATE,'
|| ' BATCH_END_DATE_' || ENVIRONMENT || ' = NULL'
|| ' WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)'
USING BATCH_STATUS, BATCH_JOB_NAME, BATCH_USER_ID;
ELSE
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET'
|| ' BATCH_STATUS_' || ENVIRONMENT || ' = :BATCH_STATUS,'
|| ' BATCH_JOB_NAME_' || ENVIRONMENT || ' = :BATCH_JOB_NAME,'
|| ' BATCH_END_DATE_' || ENVIRONMENT || ' = SYSDATE'
|| ' WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)'
USING BATCH_STATUS, BATCH_JOB_NAME;
END IF;
END;
以下过程失败并出现 "ORA-0097: missing equal sign error"。
CREATE PROCEDURE AMEPSA.USP_ETL_BATCH_MASTER_UPDATE
(ENVIRONMENT in VARCHAR2, BATCH_STATUS in VARCHAR2, BATCH_USER_ID VARCHAR2, BATCH_JOB_NAME VARCHAR2)
AS
BEGIN
IF (BATCH_STATUS = 'Running') THEN
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_' || ENVIRONMENT || ' = ' || '''' || BATCH_STATUS || '''' || ',
BATCH_JOB_NAME_' || ENVIRONMENT || ' = ' || '''' || BATCH_JOB_NAME || '''' || ',' ||
'BATCH_USER_ID_' || ENVIRONMENT || ' = ' || '''' || BATCH_USER_ID || '''' || ',' ||
'BATCH_START_DATE_' || ENVIRONMENT || ' = TO_DATE(' || '''' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH24:MI:SS') || '''' || ', ' || '''' || 'MM/DD/YYYY HH24:MI:SS' || '''' || ') ' || ',' ||
'BATCH_END_DATE_' || ENVIRONMENT || ' = ' || 'NULL' || '
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)';
ELSE
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_' || ENVIRONMENT || ' = ' || '''' || BATCH_STATUS || '''' || ',
BATCH_JOB_NAME_' || ENVIRONMENT || ' = ' || '''' || BATCH_JOB_NAME || '''' || ',' ||
'BATCH_END_DATE_' || ENVIRONMENT || ' = ' || 'TO_DATE(' || '''' || TO_CHAR(SYSDATE, 'MM/DD/YYYY HH24:MI:SS') || '''' || ', ' || '''' || 'MM/DD/YYYY HH24:MI:SS' || '''' || ')
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)';
END IF;
COMMIT;
END;
GO
在调试问题时,我们用 DBMS_OUTPUT.PUT_LINE 语句替换了 EXECUTE IMMEDIATE 语句。这样做之后,该过程返回了一个字符串(如下),该字符串成功执行且没有语法错误。
UPDATE AMEPSA.ETL_BATCH_MASTER
SET BATCH_STATUS_STAGE = 'Running',
BATCH_JOB_NAME_STAGE = 'wf_TADM_Stage',
BATCH_END_DATE_STAGE = TO_DATE('08/14/2017 15:42:00', 'MM/DD/YYYY HH24:MI:SS')
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)
当从 DBMS_OUTPUT.PUT_LINE 语句返回的结果字符串在语法上正确时,为什么 EXECUTE IMMEDIATE 语句会认为它缺少等号?
来自 Informatica 的完全异常:
Severity: ERROR Timestamp: 8/15/2017 9:46:10 AM Node: didre2007 Thread: TRANSF_1_1_1 Process ID: 9072 Message Code: CMN_1022 Message: Database driver error... CMN_1022 [ ORA-00927: missing equal sign ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 14 ORA-06512: at line 2
Database driver error... Function Name : ExecuteSP
Oracle Fatal Error Database driver error... Function Name : ExecuteSP
Oracle Fatal Error]
看起来传递给过程的参数值有单引号;特别是第一个,但可能是所有的。可以直接调用复制:
exec USP_ETL_BATCH_MASTER_UPDATE('''STAGE''', '''Running''', '''someuser''', '''wf_TADM_Stage''');
得到
Error report -
ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 14
ORA-06512: at line 1
00927. 00000 - "missing equal sign"
或者只是
exec USP_ETL_BATCH_MASTER_UPDATE('''STAGE''', 'Running', 'someuser', 'wf_TADM_Stage');
进入另一个分支并得到:
Error report -
ORA-00927: missing equal sign
ORA-06512: at "AMEPSA.USP_ETL_BATCH_MASTER_UPDATE", line 6
ORA-06512: at line 1
00927. 00000 - "missing equal sign"
通过调试显示代码在执行之前,您可以看到它最终尝试 运行 这个:
UPDATE AMEPSA.ETL_BATCH_MASTER SET
BATCH_STATUS_'STAGE' = 'Running',
BATCH_JOB_NAME_'STAGE' = 'wf_TADM_Stage',BATCH_USER_ID_'STAGE' = 'someuser',BATCH_START_DATE_'STAGE' = TO_DATE('08/15/2017 19:37:00', 'MM/DD/YYYY HH24:MI:SS') ,BATCH_END_DATE_'STAGE' = NULL
WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)
引用不当; BATCH_STATUS_'STAGE'
构造抛出异常。
如果在没有那些额外的单引号的情况下调用,您所展示的内容在任一分支中都有效。
因此,您需要调查为什么 Informatica 添加这些单引号——可能只是开发人员对如何将字符串作为参数处理感到困惑——并停止这样做。问题不在您显示的代码中,并且在没有看到 Informatica 代码的情况下,我无法更具体地说明应该如何修复它。
顺便说一句,在评论中提到您可以通过 using
子句使用绑定变量,而不是将 sysdate
转换为字符串并返回;这与您收到的错误无关,但可能看起来像:
CREATE PROCEDURE AMEPSA.USP_ETL_BATCH_MASTER_UPDATE
(ENVIRONMENT in VARCHAR2, BATCH_STATUS in VARCHAR2, BATCH_USER_ID VARCHAR2, BATCH_JOB_NAME VARCHAR2)
AS
BEGIN
IF (BATCH_STATUS = 'Running') THEN
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET'
|| ' BATCH_STATUS_' || ENVIRONMENT || ' = :BATCH_STATUS,'
|| ' BATCH_JOB_NAME_' || ENVIRONMENT || ' = :BATCH_JOB_NAME,'
|| ' BATCH_USER_ID_' || ENVIRONMENT || ' = :BATCH_USER_ID,'
|| ' BATCH_START_DATE_' || ENVIRONMENT || ' = SYSDATE,'
|| ' BATCH_END_DATE_' || ENVIRONMENT || ' = NULL'
|| ' WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)'
USING BATCH_STATUS, BATCH_JOB_NAME, BATCH_USER_ID;
ELSE
EXECUTE IMMEDIATE 'UPDATE AMEPSA.ETL_BATCH_MASTER SET'
|| ' BATCH_STATUS_' || ENVIRONMENT || ' = :BATCH_STATUS,'
|| ' BATCH_JOB_NAME_' || ENVIRONMENT || ' = :BATCH_JOB_NAME,'
|| ' BATCH_END_DATE_' || ENVIRONMENT || ' = SYSDATE'
|| ' WHERE BATCH_NBR = (SELECT MAX(BATCH_NBR) FROM AMEPSA.ETL_BATCH_MASTER)'
USING BATCH_STATUS, BATCH_JOB_NAME;
END IF;
END;