ORA-00933: SQL 命令未在存储过程中正确结束
Posted
技术标签:
【中文标题】ORA-00933: SQL 命令未在存储过程中正确结束【英文标题】:ORA-00933: SQL command not properly ended in stored procedure 【发布时间】:2017-08-29 10:19:13 【问题描述】:create or replace PROCEDURE SEC_YIELD_DOD_COMPARE_RPT(
-- IN parameters
reportingDate IN DATE,
P_PORTFOLIO_ID IN NUMERIC,
HOLDING_SECURITY_ID_PARAM IN VARCHAR2,
derYieldCalcEngineCd IN VARCHAR2,
-- OUT for INSTRUMENT
INSTRUMENT_CUR OUT SYS_REFCURSOR,
-- OUT for PORTFOLIO
PORTFOLIO_CUR OUT SYS_REFCURSOR )
AS
instrument_sids instrument_sids_table := instrument_sids_table();
portfolio_sids portfolio_sids_table := portfolio_sids_table();
queryPortfolio VARCHAR2(1500);
queryInstrument VARCHAR2(1500);
queryComplement VARCHAR2(1500);
BEGIN
queryPortfolio:=' SELECT PORTFOLIO_SIDS_RECORD( c1, c2, c3 )
FROM
(SELECT PHS.PORTFOLIO_SID AS c1,
NULL AS c2,
PHS.TRADABLE_ENTITY_SID AS c3
FROM PORTFOLIO_HOLDING_SNAPSHOT PHS
INNER JOIN PORTFOLIO P
ON P.PORTFOLIO_SID = PHS.PORTFOLIO_SID
INNER JOIN TRADABLE_ENTITY TE
ON PHS.TRADABLE_ENTITY_SID = TE.TRADABLE_ENTITY_SID
INNER JOIN INSTRUMENT I
ON TE.INSTRUMENT_SID = I.INSTRUMENT_SID
INNER JOIN TRADABLE_ENTITY_SNAPSHOT TES
ON TE.TRADABLE_ENTITY_SID = TES.TRADABLE_ENTITY_SID
WHERE PHS.REPORTING_DT=:1
AND TES.REPORTING_DT=:2
AND P.CALCULATE_SEC_YIELD_IND = ''Y'')';
queryInstrument:='SELECT INSTRUMENT_SIDS_RECORD(INSTRUMENT_SID, TRADABLE_ENTITY_SID)
FROM
( SELECT DISTINCT TE.INSTRUMENT_SID,
TE.TRADABLE_ENTITY_SID
FROM TRADABLE_ENTITY TE
INNER JOIN PORTFOLIO_HOLDING_SNAPSHOT PHS
ON PHS.TRADABLE_ENTITY_SID = TE.TRADABLE_ENTITY_SID
INNER JOIN PORTFOLIO P
ON PHS.PORTFOLIO_SID = P.PORTFOLIO_SID
INNER JOIN INSTRUMENT I
ON TE.INSTRUMENT_SID = I.INSTRUMENT_SID
INNER JOIN TRADABLE_ENTITY_SNAPSHOT TES
ON TE.TRADABLE_ENTITY_SID = TES.TRADABLE_ENTITY_SID
WHERE P.CALCULATE_SEC_YIELD_IND = ''Y''
AND PHS.REPORTING_DT = :1
AND TES.REPORTING_DT = :2)';
-- Populate instrument IDs --
IF P_PORTFOLIO_ID IS NOT NULL THEN
IF HOLDING_SECURITY_ID_PARAM IS NOT NULL THEN
IF derYieldCalcEngineCd IS NOT NULL THEN
-- P_PORTFOLIO_ID AND HOLDING_SECURITY_ID_PARAM AND derYieldCalcEngineCd
queryComplement:=' AND P.PORTFOLIO_ID=:3 AND PHS.HOLDING_SECURITY_ID =:4 AND TES.DER_YIELD_CALC_ENGINE_CD = :5';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
ELSE
-- P_PORTFOLIO_ID AND HOLDING_SECURITY_ID_PARAM
queryComplement:=' AND P.PORTFOLIO_ID=:3 AND PHS.HOLDING_SECURITY_ID =:4';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM;
END IF;
ELSE
IF derYieldCalcEngineCd IS NOT NULL THEN
-- P_PORTFOLIO_ID AND derYieldCalcEngineCd
queryComplement:=' AND P.PORTFOLIO_ID=:3 AND TES.DER_YIELD_CALC_ENGINE_CD = :4';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, derYieldCalcEngineCd;
ELSE
-- reportingDate, P_PORTFOLIO_ID
queryComplement:=' AND P.PORTFOLIO_ID=:3';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID;
END IF;
END IF;
ELSE
--FUND NUMBER IS NULL
IF HOLDING_SECURITY_ID_PARAM IS NOT NULL THEN
IF derYieldCalcEngineCd IS NOT NULL THEN
--HOLDING_SECURITY_ID_PARAM and derYieldCalcEngineCd , NO FUND NUMBER
queryComplement:=' AND PHS.HOLDING_SECURITY_ID =:3 AND TES.DER_YIELD_CALC_ENGINE_CD = :4';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
ELSE
--ONLY HOLDING_SECURITY_ID_PARAM
queryComplement:=' AND PHS.HOLDING_SECURITY_ID =:3 ';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM;
END IF;
ELSE
--ONLY derYieldCalcEngineCd
IF derYieldCalcEngineCd IS NOT NULL THEN
queryComplement:=' AND TES.DER_YIELD_CALC_ENGINE_CD = :3';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate, derYieldCalcEngineCd;
ELSE
-- ONLY reportingDate
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate;
END IF;
END IF;
END IF;
当我执行这个存储过程时,它显示给我 ORA-00933: SQL 命令未正确结束 ORA-06512:在“FAYAODSDEV01.SEC_YIELD_DOD_COMPARE_RPT”,第 112 行 ORA-06512:在第 14 行。
没有一行缺少分号或任何其他语法内容。 我怀疑问题出在字符串 queryPortfolio 或 查询仪器。
但是,我无法弄清楚确切的问题出在哪里。
由于某种原因,它提到了第 14 行。
有什么想法吗? 提前致谢。
【问题讨论】:
@vc74 ,是的。它运作良好。它给了我输出。 我不太了解 Oracle,但您使用的是:1
到 :5
,这似乎是参数。但是您似乎只“使用”了两个或三个值。
【参考方案1】:
create or replace PROCEDURE SEC_YIELD_DOD_COMPARE_RPT(
-- IN parameters
reportingDate IN DATE,
P_PORTFOLIO_ID IN NUMERIC,
HOLDING_SECURITY_ID_PARAM IN VARCHAR2,
derYieldCalcEngineCd IN VARCHAR2,
-- OUT for INSTRUMENT
INSTRUMENT_CUR OUT SYS_REFCURSOR,
-- OUT for PORTFOLIO
PORTFOLIO_CUR OUT SYS_REFCURSOR )
AS
instrument_sids instrument_sids_table := instrument_sids_table();
portfolio_sids portfolio_sids_table := portfolio_sids_table();
queryPortfolio VARCHAR2(1500);
queryInstrument VARCHAR2(1500);
queryComplement VARCHAR2(1500);
BEGIN
queryPortfolio:='SELECT PORTFOLIO_SIDS_RECORD( c1, c2, c3 )
FROM
(SELECT PHS.PORTFOLIO_SID AS c1,
NULL AS c2,
PHS.TRADABLE_ENTITY_SID AS c3
FROM PORTFOLIO_HOLDING_SNAPSHOT PHS
INNER JOIN PORTFOLIO P
ON P.PORTFOLIO_SID = PHS.PORTFOLIO_SID
INNER JOIN TRADABLE_ENTITY TE
ON PHS.TRADABLE_ENTITY_SID = TE.TRADABLE_ENTITY_SID
INNER JOIN INSTRUMENT I
ON TE.INSTRUMENT_SID = I.INSTRUMENT_SID
INNER JOIN TRADABLE_ENTITY_SNAPSHOT TES
ON TE.TRADABLE_ENTITY_SID = TES.TRADABLE_ENTITY_SID
WHERE PHS.REPORTING_DT=:1
AND TES.REPORTING_DT=:2
AND P.CALCULATE_SEC_YIELD_IND = ''Y'')';
queryInstrument:='SELECT INSTRUMENT_SIDS_RECORD(INSTRUMENT_SID, TRADABLE_ENTITY_SID)
FROM
( SELECT DISTINCT TE.INSTRUMENT_SID,
TE.TRADABLE_ENTITY_SID
FROM TRADABLE_ENTITY TE
INNER JOIN PORTFOLIO_HOLDING_SNAPSHOT PHS
ON PHS.TRADABLE_ENTITY_SID = TE.TRADABLE_ENTITY_SID
INNER JOIN PORTFOLIO P
ON PHS.PORTFOLIO_SID = P.PORTFOLIO_SID
INNER JOIN INSTRUMENT I
ON TE.INSTRUMENT_SID = I.INSTRUMENT_SID
INNER JOIN TRADABLE_ENTITY_SNAPSHOT TES
ON TE.TRADABLE_ENTITY_SID = TES.TRADABLE_ENTITY_SID
WHERE P.CALCULATE_SEC_YIELD_IND = ''Y''
AND PHS.REPORTING_DT = :1
AND TES.REPORTING_DT = :2)';
-- Populate instrument IDs --
IF P_PORTFOLIO_ID IS NOT NULL THEN
IF HOLDING_SECURITY_ID_PARAM IS NOT NULL THEN
IF derYieldCalcEngineCd IS NOT NULL THEN
-- P_PORTFOLIO_ID AND HOLDING_SECURITY_ID_PARAM AND derYieldCalcEngineCd
queryComplement:=' AND P.PORTFOLIO_ID=:3 AND PHS.HOLDING_SECURITY_ID =:4 AND TES.DER_YIELD_CALC_ENGINE_CD = :5';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
ELSE
-- P_PORTFOLIO_ID AND HOLDING_SECURITY_ID_PARAM
queryComplement:=' AND P.PORTFOLIO_ID=:3 AND PHS.HOLDING_SECURITY_ID =:4';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, HOLDING_SECURITY_ID_PARAM;
END IF;
ELSE
IF derYieldCalcEngineCd IS NOT NULL THEN
-- P_PORTFOLIO_ID AND derYieldCalcEngineCd
queryComplement:=' AND P.PORTFOLIO_ID=:3 AND TES.DER_YIELD_CALC_ENGINE_CD = :4';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID, derYieldCalcEngineCd;
ELSE
-- reportingDate, P_PORTFOLIO_ID
queryComplement:=' AND P.PORTFOLIO_ID=:3';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate,P_PORTFOLIO_ID;
END IF;
END IF;
ELSE
--FUND NUMBER IS NULL
IF HOLDING_SECURITY_ID_PARAM IS NOT NULL THEN
IF derYieldCalcEngineCd IS NOT NULL THEN
--HOLDING_SECURITY_ID_PARAM and derYieldCalcEngineCd , NO FUND NUMBER
queryComplement:=' AND PHS.HOLDING_SECURITY_ID =:3 AND TES.DER_YIELD_CALC_ENGINE_CD = :4';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM, derYieldCalcEngineCd;
ELSE
--ONLY HOLDING_SECURITY_ID_PARAM
queryComplement:=' AND PHS.HOLDING_SECURITY_ID =:3 ';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate, HOLDING_SECURITY_ID_PARAM;
END IF;
ELSE
--ONLY derYieldCalcEngineCd
IF derYieldCalcEngineCd IS NOT NULL THEN
queryComplement:=' AND TES.DER_YIELD_CALC_ENGINE_CD = :3';
queryPortfolio := queryPortfolio || queryComplement;
queryInstrument := queryInstrument || queryComplement;
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate, derYieldCalcEngineCd;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate, derYieldCalcEngineCd;
ELSE
-- ONLY reportingDate
EXECUTE IMMEDIATE queryPortfolio BULK COLLECT INTO PORTFOLIO_SIDS USING reportingDate,reportingDate;
EXECUTE IMMEDIATE queryInstrument BULK COLLECT INTO INSTRUMENT_SIDS USING reportingDate,reportingDate;
END IF;
END IF;
END IF;
结束;
试试上面的代码。
您忘记在程序结束时添加 END;
。
我已经添加了。
它一定会对你有所帮助。
【讨论】:
【参考方案2】:我们无法远程调试您动态生成的 SQL。这是你必须自己解决的问题。
动态 SQL 难以编码和调试。主要问题是将编译错误变成运行时错误。但是由于该语句是动态的,因此在您找到错误之前没有任何来源可供研究。
但是,您可以通过检测代码来让自己更轻松。放入一些跟踪语句,最好记录到表或文件,但使用dbms_output.put_line()
,如果这就是你所拥有的。记录你去哪个分支。记录生成的 SQL 语句。甚至记录正在运行的参数。
拥有足够的信息来理解问题至少是解决问题的百分之五十。
【讨论】:
以上是关于ORA-00933: SQL 命令未在存储过程中正确结束的主要内容,如果未能解决你的问题,请参考以下文章
如何解决 ORA-00933:SQL 命令未在 oracle 中正确结束?
我将如何修复这些“ORA-00933:SQL 命令未正确结束”“ORA-00923:未在预期位置找到 FROM 关键字”错误?
从表内连接中删除 - ORA-00933:SQL 命令未正确结束
ORA-00933: SQL 命令未正确结束 00933. 00000 - “SQL 命令未正确结束