0

我尝试在 oracle 数据库中触发器的 where 子句中使用 SYSDATE,但代码抛出“ORA-01722:无效数字”异常。

 SELECT 'ATT' || '-' || TO_CHAR(SYSDATE, 'YY') || '-' 
       || LPAD((SELECT TO_NUMBER(COUNT(*)) 
                FROM  ATT_REQUEST_DATA 
                WHERE REQID like ('ATT-' + TO_CHAR(SYSDATE, 'YY') + '-%')) + 1, '4', '0')

你知道,我应该如何修复它?


这是表的定义

CREATE TABLE ATT_REQUEST_DATA
( REQID VARCHAR2(50),
  REQ_SUBID NUMBER,
  FLAG_ID NUMBER,
  DATE_FROM DATE,
  DATE_TO DATE,
  CREATED_DATE DATE,

  CONSTRAINT ATT_REQUEST_DATA_PK PRIMARY KEY (REQID, REQ_SUBID)
);
/

这是插入数据的示例

INSERT INTO ATT_REQUEST_DATA (FLAG_ID, DATE_FROM, DATE_TO, CREATED_DATE)
VALUES (2, SYSDATE, SYSDATE, SYSDATE);

这是错误输出

ORA-01722:无效编号
ORA-06512:在“PD.ATT_REQUEST_DATA_TRG_ID”第 4 行
ORA-04088:执行触发器“PD.ATT_REQUEST_DATA_TRG_ID”时出错


这是整个触发器

CREATE OR REPLACE TRIGGER ATT_REQUEST_DATA_TRG_ID
BEFORE INSERT ON ATT_REQUEST_DATA FOR EACH ROW
BEGIN
    IF (:NEW.REQID IS NULL) THEN

        SELECT 'ATT' || '-' || TO_CHAR(SYSDATE, 'YY') || '-' || LPAD((SELECT TO_NUMBER(COUNT(*)) FROM  ATT_REQUEST_DATA WHERE REQID like ('ATT-' + TO_CHAR(SYSDATE, 'YY') + '-%')) + 1, '4', '0')
        INTO   :NEW.REQID
        FROM DUAL;

        SELECT (SELECT COUNT(*) FROM ATT_REQUEST_DATA WHERE REQID = :NEW.REQID) + 1
        INTO   :NEW.REQ_SUBID 
        FROM DUAL;


    END IF;

END;
/
4

2 回答 2

0

导致您的问题的不是使用 SYSDATE

你的代码有几个奇怪的地方。首先有这个宝石:TO_NUMBER(COUNT(*))count()返回一个数字,因此无需强制转换它;幸运的是,Oracle 足够聪明,知道这一点,所以这不是 ORA-01722 错误的根源。

不,那是因为这些操作:('ATT-' + TO_CHAR(SYSDATE, 'YY') + '-%')). 在 Oracle 中,SQL+是一个算术运算符:SQL 引擎认为您要对 进行加法运算 ,而我们不能对字符串进行加法运算。要解决此问题,请替换为连接运算符:'ATT-'TO_CHAR(SYSDATE, 'YY')+||

('ATT-' || TO_CHAR(SYSDATE, 'YY') || '-%')) 
于 2017-07-17T08:29:05.540 回答
0

尝试这个:

with 
  p  as (select 'ATT' || '-' || TO_CHAR(SYSDATE, 'YY') || '-' pattern from dual )
  , cnt as (  
    SELECT pattern, COUNT(*) cnt 
    FROM  ATT_REQUEST_DATA cross join p 
    WHERE REQID like pattern || '%')
  , res as (select pattern || LPAD(  cnt + 1, '4', '0') from  cnt )
select * from res;

http://sqlfiddle.com/#!4/c971a6/5

注意,我使用 WITH 子句将你的 SQL 的子部分分解成更小的块,以使调试更容易。您可以安全地将其重新组合成一个不带 WITH 子句的 Select

于 2017-07-17T08:29:35.113 回答