存储过程停止工作

Posted

技术标签:

【中文标题】存储过程停止工作【英文标题】:Stored procedure stopped working 【发布时间】:2014-11-17 13:49:38 【问题描述】:

我有一个关于存储过程的问题。我编写的存储过程允许第三方提供商将数据插入我的数据库。直到 5 天前,当不再插入任何数据时,它一直都能正常工作。在 SQL 方面,我真的是一个完全的菜鸟,所以我不知道从哪里开始调查可能是什么错误。非常感谢任何帮助、见解和建议。提前致谢。附上代码。

create or replace PROCEDURE               "GET_DROP_COPY"
(
  P_BEGINSTRING IN VARCHAR2
, P_BODYLENGTH IN VARCHAR2
, P_MSGTYPE IN VARCHAR2
, P_MSGSEQNUM IN VARCHAR2
, P_SENDERCOMPID IN VARCHAR2
, P_SENDINGTIME IN VARCHAR2
, P_TARGETCOMPID IN VARCHAR2
, P_TARGETSUBID IN VARCHAR2
, P_AVGPX IN VARCHAR2
, P_CLORDID IN VARCHAR2
, P_CUMQTY IN VARCHAR2
, P_CURRENCY IN CHAR
, P_EXECID IN VARCHAR2
, P_SECURITYIDSOURCE IN NUMBER
, P_LASTPX IN NUMBER
, P_LASTQTY IN NUMBER
, P_ORDERID IN VARCHAR2
, P_ORDERQTY IN NUMBER
, P_ORDSTATUS IN VARCHAR2
, P_PRICE IN NUMBER
, P_ORDTYPE IN VARCHAR2
, P_SECURITYID IN VARCHAR2
, P_SIDE IN VARCHAR2
, P_FIELD55 IN VARCHAR2
, P_TIMEINFORCE IN VARCHAR2
, P_TRANSACTTIME IN VARCHAR2
, P_SETTLTYPE IN VARCHAR2
, P_TRADEDATE IN VARCHAR2
, P_EXDESTINATION IN VARCHAR2
, P_EXECTYPE IN VARCHAR2
, P_LEAVESQTY IN VARCHAR2
, P_SECURITYTYPE IN VARCHAR2
, P_SECONDARYORDERID IN VARCHAR2
, P_SECURITYEXCHANGE IN VARCHAR2
, P_ROUNDLOTBOOK IN NUMBER
, P_COPYMSGINDICATOR IN VARCHAR2
, P_REPEATING_GROUP IN NUMBER
, P_PARTY_ID IN VARCHAR2
, P_PARTYIDSOURCE IN VARCHAR2
, P_PARTYROLE IN NUMBER
, P_PARTYID2 IN VARCHAR2
, P_PARTYIDSOURCE2 IN VARCHAR2
, P_PARTYROLE2 IN NUMBER
, P_PARTYID3 IN VARCHAR2
, P_PARTYIDSOURCE3 IN VARCHAR2
, P_PARTYROLE3 IN NUMBER
, P_CHECKSUM IN NUMBER
) AS
l_count     NUMBER;
l_modpor    NUMBER(1,0);
l_logid     NUMBER;
err_num     NUMBER;
err_msg     VARCHAR2(100);

BEGIN

SELECT NVL(MAX(ID),0) INTO l_logid
FROM LOG_PROCEDURE;

IF l_logid = 0 THEN
  l_logid := 1;
ELSE
  l_logid := l_logid + 1;
END IF;

INSERT INTO LOG_PROCEDURE (ID, ETL, INICIO, TRAZA, TABLA)
VALUES(l_logid, 'GET_DROP_COPY', SYSDATE, 'INSERT RECORD. ',
'DROP_COPY');
COMMIT;

  INSERT INTO DROP_COPY (BEGINSTRING, BODYLENGTH, MSGTYPE, MSGSEQNUM,
SENDERCOMPID, SENDINGTIME, TARGETCOMPID, TARGETSUBID, AVGPX, CLORDID,
CUMQTY, CURRENCY, EXECID, SECURITYIDSOURCE, LASTPX, LASTQTY, ORDERID,
ORDERQTY, ORDSTATUS, PRICE, ORDTYPE, SECURITYID, SIDE, FIELD55,
TIMEINFORCE, TRANSACTTIME, SETTLTYPE, TRADEDATE, EXDESTINATION,
EXECTYPE, LEAVESQTY, SECURITYTYPE, SECONDARYORDERID, SECURITYEXCHANGE,
ROUNDLOTBOOK, COPYMSGINDICATOR, REPEATING_GROUP, PARTY_ID,
PARTYIDSOURCE, PARTYROLE, PARTYID2, PARTYIDSOURCE2, PARTYROLE2,
PARTYID3, PARTYIDSOURCE3, PARTYROLE3, CHECKSUM)
    VALUES(P_BEGINSTRING, P_BODYLENGTH, P_MSGTYPE, P_MSGSEQNUM,
P_SENDERCOMPID, P_SENDINGTIME, P_TARGETCOMPID, P_TARGETSUBID, P_AVGPX,
P_CLORDID, P_CUMQTY, P_CURRENCY, P_EXECID, P_SECURITYIDSOURCE, P_LASTPX,
P_LASTQTY, P_ORDERID, P_ORDERQTY, P_ORDSTATUS, P_PRICE, P_ORDTYPE,
P_SECURITYID, P_SIDE, P_FIELD55, P_TIMEINFORCE, P_TRANSACTTIME,
P_SETTLTYPE, P_TRADEDATE, P_EXDESTINATION, P_EXECTYPE, P_LEAVESQTY,
P_SECURITYTYPE, P_SECONDARYORDERID, P_SECURITYEXCHANGE, P_ROUNDLOTBOOK,
P_COPYMSGINDICATOR, P_REPEATING_GROUP, P_PARTY_ID, P_PARTYIDSOURCE,
P_PARTYROLE, P_PARTYID2, P_PARTYIDSOURCE2, P_PARTYROLE2, P_PARTYID3,
P_PARTYIDSOURCE3, P_PARTYROLE3, P_CHECKSUM);

  l_count := TO_CHAR(SQL%ROWCOUNT);

UPDATE LOG_PROCEDURE
SET FIN = SYSDATE,
        ESTADO = 'OK',
        TRAZA = TRAZA || l_count || ' REGISTRO(s) INSERTADO(s).'
WHERE ID = l_logid;


COMMIT;

IF (P_PARTY_ID IN ('009', '036', '016', '003') OR P_PARTYID2 IN ('009', '036', '016', '003') OR P_PARTYID3 IN ('009', '036', '016', '003')) AND (P_ORDERID NOT LIKE'%SER%') THEN

  IF ( P_EXECTYPE NOT IN ('0', '4') AND ((P_PARTYROLE = 7 AND P_PARTY_ID = '058') OR  (P_PARTYROLE2 = 7 AND P_PARTYID2 = '058') OR (P_PARTYROLE3 = 7 AND P_PARTYID3 = '058'))) THEN
    l_modpor := 1;
  ELSE
    l_modpor := 0;
  END IF;

    INSERT INTO EQUITY_PORTFOLIO_DCMOV
       ( BEGINSTRING, BODYLENGTH, MSGTYPE, MSGSEQNUM, SENDERCOMPID, SENDINGTIME, TARGETCOMPID, TARGETSUBID, AVGPX, CLORDID,
         CUMQTY, CURRENCY, EXECID, SECURITYIDSOURCE, LASTPX, LASTQTY, ORDERID,  ORDERQTY, ORDSTATUS, PRICE, ORDTYPE, SECURITYID, SIDE, FIELD55,
         TIMEINFORCE, TRANSACTTIME, SETTLTYPE, TRADEDATE, EXDESTINATION, EXECTYPE, LEAVESQTY, SECURITYTYPE, SECONDARYORDERID, SECURITYEXCHANGE,
         ROUNDLOTBOOK, COPYMSGINDICATOR, REPEATING_GROUP, PARTY_ID, PARTYIDSOURCE, PARTYROLE, PARTYID2, PARTYIDSOURCE2, PARTYROLE2,
         PARTYID3, PARTYIDSOURCE3, PARTYROLE3, CHECKSUM, ORIGEN, MODPOR
       )
     VALUES( P_BEGINSTRING, P_BODYLENGTH, P_MSGTYPE, P_MSGSEQNUM, P_SENDERCOMPID, TO_TIMESTAMP(P_SENDINGTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_TARGETCOMPID, P_TARGETSUBID, P_AVGPX,
             P_CLORDID, P_CUMQTY, TRIM(P_CURRENCY), P_EXECID, P_SECURITYIDSOURCE, P_LASTPX, P_LASTQTY, P_ORDERID, P_ORDERQTY, P_ORDSTATUS, P_PRICE, P_ORDTYPE,
             P_SECURITYID, P_SIDE, P_FIELD55, P_TIMEINFORCE, TO_TIMESTAMP(P_TRANSACTTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_SETTLTYPE, P_TRADEDATE, P_EXDESTINATION, P_EXECTYPE, P_LEAVESQTY,
             P_SECURITYTYPE, P_SECONDARYORDERID, TRIM(P_SECURITYEXCHANGE), P_ROUNDLOTBOOK, TRIM(P_COPYMSGINDICATOR), P_REPEATING_GROUP, P_PARTY_ID, P_PARTYIDSOURCE,
             P_PARTYROLE, P_PARTYID2, P_PARTYIDSOURCE2, P_PARTYROLE2, P_PARTYID3, P_PARTYIDSOURCE3, P_PARTYROLE3, P_CHECKSUM, 'LOCAL', l_modpor
           );  

     SELECT COUNT(*) INTO l_count
       FROM EQUITY_PORTFOLIO
         WHERE SECURITYID = P_SECURITYID;

     IF l_count >= 1 AND l_modpor = 1 THEN
       ACTUALIZA_EQUITY_PORTFOLIO (P_ORDERID, P_SECURITYID, P_PRICE, P_ORDERQTY, P_EXECTYPE, P_ORDSTATUS, P_SIDE, TO_TIMESTAMP(P_SENDINGTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), TO_TIMESTAMP(P_TRANSACTTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_TRADEDATE, P_LASTPX, P_LASTQTY, l_modpor);
     ELSE
       IF l_count = 0 THEN

         INSERT INTO EQUITY_PORTFOLIO(SECURITYID, SECURITY_ID, ID_ISIN, POSITION, POSITION_INI, AAAAMMDD, CURRENCY)
           SELECT P_SECURITYID, EQDES.BLOOMBERG_TICKER, EQDES.ID_ISIN, 0, 0, P_TRADEDATE, CURRENCY
              FROM EQUITY_DESCRIPTOR EQDES
               WHERE ID_EXCH_SYMBOL = P_SECURITYID;
         COMMIT;

        ACTUALIZA_EQUITY_PORTFOLIO (P_ORDERID, P_SECURITYID, P_PRICE, P_ORDERQTY, P_EXECTYPE, P_ORDSTATUS, P_SIDE, TO_TIMESTAMP(P_SENDINGTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), TO_TIMESTAMP(P_TRANSACTTIME, 'YYYYMMDD-HH24:MI:SS.FF3'), P_TRADEDATE, P_LASTPX, P_LASTQTY, l_modpor);

       END IF;
    END IF;
  END IF;    



EXCEPTION
WHEN OTHERS THEN

err_num := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 100);

INSERT INTO DROP_COPY_ERROR (BEGINSTRING, BODYLENGTH, MSGTYPE, MSGSEQNUM,
SENDERCOMPID, SENDINGTIME, TARGETCOMPID, TARGETSUBID, AVGPX, CLORDID,
CUMQTY, CURRENCY, EXECID, SECURITYIDSOURCE, LASTPX, LASTQTY, ORDERID,
ORDERQTY, ORDSTATUS, PRICE, ORDTYPE, SECURITYID, SIDE, FIELD55,
TIMEINFORCE, TRANSACTTIME, SETTLTYPE, TRADEDATE, EXDESTINATION,
EXECTYPE, LEAVESQTY, SECURITYTYPE, SECONDARYORDERID, SECURITYEXCHANGE,
ROUNDLOTBOOK, COPYMSGINDICATOR, REPEATING_GROUP, PARTY_ID,
PARTYIDSOURCE, PARTYROLE, PARTYID2, PARTYIDSOURCE2, PARTYROLE2,
PARTYID3, PARTYIDSOURCE3, PARTYROLE3, CHECKSUM, LOGID)
    VALUES(P_BEGINSTRING, P_BODYLENGTH, P_MSGTYPE, P_MSGSEQNUM,
P_SENDERCOMPID, P_SENDINGTIME, P_TARGETCOMPID, P_TARGETSUBID, P_AVGPX,
P_CLORDID, P_CUMQTY, P_CURRENCY, P_EXECID, P_SECURITYIDSOURCE, P_LASTPX,
P_LASTQTY, P_ORDERID, P_ORDERQTY, P_ORDSTATUS, P_PRICE, P_ORDTYPE,
P_SECURITYID, P_SIDE, P_FIELD55, P_TIMEINFORCE, P_TRANSACTTIME,
P_SETTLTYPE, P_TRADEDATE, P_EXDESTINATION, P_EXECTYPE, P_LEAVESQTY,
P_SECURITYTYPE, P_SECONDARYORDERID, P_SECURITYEXCHANGE, P_ROUNDLOTBOOK,
P_COPYMSGINDICATOR, P_REPEATING_GROUP, P_PARTY_ID, P_PARTYIDSOURCE,
P_PARTYROLE, P_PARTYID2, P_PARTYIDSOURCE2, P_PARTYROLE2, P_PARTYID3,
P_PARTYIDSOURCE3, P_PARTYROLE3, P_CHECKSUM, l_logid);

UPDATE LOG_PROCEDURE
SET FIN = SYSDATE,
            ESTADO = 'ERROR',
            CODERR = err_num,
            MSGERR = err_msg
WHERE ID = l_logid;

COMMIT;

END GET_DROP_COPY;

这是我运行程序时的输出:

正在连接到数据库 CLBCB_TRADER。 ORA-01400: 无法将 NULL 插入 ("CLBCBTRADER"."DROP_COPY_ERROR"."SENDINGTIME") ORA-06512:在“CLBCBTRADER.GET_DROP_COPY”,第 155 行 ORA-01400: 无法将 NULL 插入 ("CLBCBTRADER"."DROP_COPY"."SENDINGTIME") ORA-06512:在第 98 行 进程退出。 与数据库 CLBCB_TRADER 断开连接。

另外,我应该提一下“SENDINGTIME”变量总是这样,所以我没有看到问题:“20141110-13:30:03.394”

【问题讨论】:

没有代码? - 您的客户究竟是如何执行程序的? 不知何故我无法发布代码。 *** 给我一个关于代码的错误消息,即使它运行得很好。 尝试复制粘贴到记事本中,然后从那里复制粘贴 好的,使用括号工作 您在使用 Oracle 吗?另外,为什么所有 VARCHAR2 参数都声明为没有大小?为它们定义尺寸。 【参考方案1】:

查看错误消息,参数P_SENDINGTIME 似乎是作为NULL 值传递的,这不是您的架构定义中允许的值。

您的第三方提供商似乎在最近几天发生了一些变化。 如果那个参数只是一个时间戳,你可以设置一个默认值来运行你的脚本,通过设置一个默认值来改变过程:

create or replace PROCEDURE "GET_DROP_COPY" (
   //...first part definition of script here

   , P_SENDINGTIME IN VARCHAR2 := ''

   //...rest definition of script here
)
   //... body of script here
END GET_DROP_COPY;

请注意:

    你应该首先询问提供者他们是否改变了 任何东西 如果您不确定该值应该是什么,这可能是一种冒险的方法 您可以使用 sysdate 来获取正确的时间戳值 - 例如:
   ...
    , P_SENDINGTIME IN VARCHAR2 := TO_CHAR(SYSDATE, 'MM.DD.YYYY HH24:MI:SS')
   ...

【讨论】:

感谢您的洞察力。那么,P_SENDINGTIME IN VARCHAR2 := '' 将允许我适应该特定字段的变化? 我会按照你的步骤并在这里发布 这将是一个默认值:如果该参数作为 NULL 传递(看起来如此),它将获得您在引号之间定义的值。【参考方案2】:

错误是告诉您您正在尝试将NULL 值插入到 GET_DROP_COPY 的 SENDINGTIME 字段中。该字段不允许使用 NULL 值。

要么:

插入一个实际值 允许在您的列中使用空值。

您可能应该查看第一个选项,因为该列可能存在不允许空值的原因。

【讨论】:

以上是关于存储过程停止工作的主要内容,如果未能解决你的问题,请参考以下文章

存储过程在 7 年后随机停止工作

长存储过程在某些 exec 之后停止返回结果,为啥?

一旦违反条件,停止存储过程的进一步执行?

弹出警报消息时如何停止SQL存储过程中的事务

Dapper 在使用存储过程更新表后停止拉连接表

如何停止在 MySQL 中执行完整的存储过程?