繁体   English   中英

Oracle SQL存储过程缺少表达式错误

[英]Oracle SQL Stored Procedure missing expression error

我正在写一个存储过程,它是一个动态的续集语句,可以从一个中间表写入另一个表。 我在编写sql和存储过程特别是新手。 我尝试在语句中添加参数,但始终收到此错误:ORA-00936:缺少表达式ORA-06512:在“ ECH_ETL_BATCH_ID.LOOKUP_TABLE_INSERT”的第26行ORA-06512:在第14行进程已退出。 我拿出参数并在值中进行了硬编码,只是试图使其正常工作,但我仍然收到相同的错误。 有什么建议么?

create or replace PROCEDURE                                                     
LOOKUP_TABLE_INSERT 
(
P_SOURCE_DB IN VARCHAR2
, P_SOURCE_TABLE IN VARCHAR2
, P_TARGET_DB IN VARCHAR2
, P_TARGET_TABLE IN VARCHAR2
, P_COLUMN_NAME IN VARCHAR2
) AS 
l_sql_statement VARCHAR2(1000);
BEGIN


l_sql_statement :=
'INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP' || 
'(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID, 
HUB_STATE_IND, ROLE_TP) ' || 
' SELECT MISSING_VALUES AS PKEY_SRC_OBJECT' ||
', 1 as VERSION_SEQ' ||
', 0 as TIMELINE_ACTION' ||
', INSERT_TS as LAST_UPDATE_DATE' ||
', MISSING_VALUES as "SRC_ROWID"' || 
', 1 as "HUB_STATE_IND"' ||
', MISSING_VALUES as ROLE_TP' || --P_COLUMN_NAME ||              
' FROM ECH_ETL_BATCH_ID.Ref_Intermediate ' || 
WHERE COLUMN_NM =' || ''||ROLE_TP||'' ||
'AND LOOKUP_TBL_NM =' || ''||C_S_LU_PTY_ROLE_TP||'';
dbms_output.put_line(l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement;
COMMIT;
END;

EXECUTE IMMEDIATE l_sql_statement;
COMMIT;
END;

你的问题是在哪里条件。 删除||

如果执行dbms_output.putline(); 你会得到陈述

要添加单引号,请检查以下解决方案

错误原因:

INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP
  (PKEY_SRC_OBJECT,
   VERSION_SEQ,
   TIMELINE_ACTION,
   LAST_UPDATE_DATE,
   SRC_ROWID,
   HUB_STATE_IND,
   ROLE_TP)
  SELECT MISSING_VALUES AS PKEY_SRC_OBJECT,
         1              as VERSION_SEQ,
         0              as TIMELINE_ACTION,
         INSERT_TS      as LAST_UPDATE_DATE,
         MISSING_VALUES as "SRC_ROWID",
         1              as "HUB_STATE_IND",
         MISSING_VALUES as ROLE_TP
    FROM ECH_ETL_BATCH_ID.Ref_Intermediate
   WHERE COLUMN_NM = || ROLE_TP ||
     AND LOOKUP_TBL_NM = || C_S_LU_PTY_ROLE_TP ||

解决方案 :

create or replace PROCEDURE                                                     
LOOKUP_TABLE_INSERT 
(
P_SOURCE_DB IN VARCHAR2
, P_SOURCE_TABLE IN VARCHAR2
, P_TARGET_DB IN VARCHAR2
, P_TARGET_TABLE IN VARCHAR2
, P_COLUMN_NAME IN VARCHAR2
) AS 
l_sql_statement VARCHAR2(1000);
BEGIN


l_sql_statement :=
'INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP' || 
'(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID, 
HUB_STATE_IND, ROLE_TP) ' || 
' SELECT MISSING_VALUES AS PKEY_SRC_OBJECT' ||
', 1 as VERSION_SEQ' ||
', 0 as TIMELINE_ACTION' ||
', INSERT_TS as LAST_UPDATE_DATE' ||
', MISSING_VALUES as "SRC_ROWID"' || 
', 1 as "HUB_STATE_IND"' ||
', MISSING_VALUES as ROLE_TP' || --P_COLUMN_NAME ||              
' FROM ECH_ETL_BATCH_ID.Ref_Intermediate ' || 
' WHERE COLUMN_NM =''' ||ROLE_TP||''     
' AND LOOKUP_TBL_NM =''' ||C_S_LU_PTY_ROLE_TP|''' ';
dbms_output.put_line(l_sql_statement);
EXECUTE IMMEDIATE l_sql_statement;
COMMIT;
END;
/

您的(已编辑)代码生成的动态语句为:

INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID, 
HUB_STATE_IND, ROLE_TP)  SELECT MISSING_VALUES AS PKEY_SRC_OBJECT, 1 as VERSION_SEQ, 0 as TIMELINE_ACTION, INSERT_TS as LAST_UPDATE_DATE, SELECT MISSING_VALUES as "SRC_ROWID", 1 as "HUB_STATE_IND", MISSING_VALUES as ROLE_TP FROM ECH_ETL_BATCH_ID.Ref_Intermediate  WHERE COLUMN_NM =||ROLE_TP|| AND LOOKUP_TBL_NM =||C_S_LU_PTY_ROLE_TP||

或分成多行并加上注释以显示其存在的问题:

INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP(PKEY_SRC_OBJECT, VERSION_SEQ,
  TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID, HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES AS PKEY_SRC_OBJECT
, 1 as VERSION_SEQ
, 0 as TIMELINE_ACTION
, INSERT_TS as LAST_UPDATE_DATE
, SELECT MISSING_VALUES as "SRC_ROWID"
--^^^^^^
, 1 as "HUB_STATE_IND"
, MISSING_VALUES as ROLE_TP
FROM ECH_ETL_BATCH_ID.Ref_Intermediate
WHERE COLUMN_NM =||ROLE_TP|| AND LOOKUP_TBL_NM =||C_S_LU_PTY_ROLE_TP||
--               ^^       ^^                    ^^                  ^^

您对此有一些问题; 大多数情况下,您有|| 嵌入在生成的语句中的奇怪位置,但是您还有一个额外的SELECT

这可能更接近您想要的内容,包括嵌入式字符串文字的转义单引号:

l_sql_statement :=
'INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP' || 
'(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID, HUB_STATE_IND, ROLE_TP) ' || 
' SELECT MISSING_VALUES AS PKEY_SRC_OBJECT' ||
', 1 as VERSION_SEQ' ||
', 0 as TIMELINE_ACTION' ||
', INSERT_TS as LAST_UPDATE_DATE' ||
', MISSING_VALUES as "SRC_ROWID"' || 
', 1 as "HUB_STATE_IND"' ||
', MISSING_VALUES as ROLE_TP' ||
' FROM ECH_ETL_BATCH_ID.Ref_Intermediate ' || 
' WHERE COLUMN_NM = ''ROLE_TP''' ||     
' AND LOOKUP_TBL_NM = ''C_S_LU_PTY_ROLE_TP''';

生成(再次拆分):

INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP(PKEY_SRC_OBJECT, VERSION_SEQ,
  TIMELINE_ACTION, LAST_UPDATE_DATE, SRC_ROWID, HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES AS PKEY_SRC_OBJECT
, 1 as VERSION_SEQ
, 0 as TIMELINE_ACTION
, INSERT_TS as LAST_UPDATE_DATE
, MISSING_VALUES as "SRC_ROWID"
, 1 as "HUB_STATE_IND"
, MISSING_VALUES as ROLE_TP
FROM ECH_ETL_BATCH_ID.Ref_Intermediate
WHERE COLUMN_NM = 'ROLE_TP'
AND LOOKUP_TBL_NM = 'C_S_LU_PTY_ROLE_TP'

您可以跨行分割字符串分配,这会简化事情,因为这会减少(或现在删除)字符串连接:

l_sql_statement :=
'INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE,
  SRC_ROWID, HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES AS PKEY_SRC_OBJECT
, 1 as VERSION_SEQ
, 0 as TIMELINE_ACTION
, INSERT_TS as LAST_UPDATE_DATE
, MISSING_VALUES as "SRC_ROWID"
, 1 as "HUB_STATE_IND"
, MISSING_VALUES as ROLE_TP
FROM ECH_ETL_BATCH_ID.Ref_Intermediate
WHERE COLUMN_NM = ''ROLE_TP''
AND LOOKUP_TBL_NM = ''C_S_LU_PTY_ROLE_TP''';

或者,您也可以使用其他报价机制来避免转义单引号。

创建动态语句时,请从有效的静态语句开始并向后工作; 并使用dbms_output显示最终生成的字符串,以便您可以对其进行验证,并在必要时手动运行它。

当然,这根本不需要是动态的,但是从您最初的问题出发,您打算在某个时候在子查询中使用过程参数。


要使用过程参数而不是必须使用的字符串文字,可以将它们串联在一起:

l_sql_statement :=
'INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE,
  SRC_ROWID, HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES AS PKEY_SRC_OBJECT
, 1 as VERSION_SEQ
, 0 as TIMELINE_ACTION
, INSERT_TS as LAST_UPDATE_DATE
, MISSING_VALUES as "SRC_ROWID"
, 1 as "HUB_STATE_IND"
, MISSING_VALUES as ROLE_TP
FROM ECH_ETL_BATCH_ID.Ref_Intermediate
WHERE COLUMN_NM = ' || P_COLUMN_NAME || '
AND LOOKUP_TBL_NM = ' || P_TARGET_TABLE;

或最好使用绑定变量:

l_sql_statement :=
'INSERT INTO ECH_ETL_BATCH_ID.C_S_LU_PTY_ROLE_TP
(PKEY_SRC_OBJECT, VERSION_SEQ, TIMELINE_ACTION, LAST_UPDATE_DATE,
  SRC_ROWID, HUB_STATE_IND, ROLE_TP)
SELECT MISSING_VALUES AS PKEY_SRC_OBJECT
, 1 as VERSION_SEQ
, 0 as TIMELINE_ACTION
, INSERT_TS as LAST_UPDATE_DATE
, MISSING_VALUES as "SRC_ROWID"
, 1 as "HUB_STATE_IND"
, MISSING_VALUES as ROLE_TP
FROM ECH_ETL_BATCH_ID.Ref_Intermediate
WHERE COLUMN_NM = :COLUMN_NAME
AND LOOKUP_TBL_NM = :TARGET_TABLE';

EXECUTE IMMEDIATE l_sql_statement USING P_COLUMN_NAME, P_TARGET_TABLE;

不过,这仍然不需要动态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM