2015-10-26 33 views
0

我在创建插入之前和更新触发器之前检查数据类型。例如,我有一个ytd_sales字段,它是NUMBER。我想制作一个触发器,如果​​有人试图在这里插入一个varchar,就会输出一条错误消息。 我试着做这样的人......SQL问题。在插入之前需要检查触发器的数据类型

IF :new.ytd_sales != NUMBER THEN 
//print the message 

但是这给编译错误。任何见解?

这里有一些代码供参考。

SHOW ERRORS; 
CREATE OR REPLACE TRIGGER before_insert_book 
BEFORE INSERT ON book 
     FOR EACH ROW 

BEGIN 
     IF :new.ISBN is NULL THEN 
       raise_application_error(-20000, 'ISBN is null, insert was not accepted. Please revise your insert statement'); 
     END IF; 
     IF :new.title is NULL THEN 
       raise_application_error(-20000, 'TITLE is null, insert was not accepted. Please revise your insert statement'); 
     END IF; 
     /* 
     IF :new.isbn != VARCHAR2 THEN 
       raise_application_error(-20001, 'isbn is of wrong type, please correct.'); 
     END IF; 

     IF :new.title != VARCHAR2 THEN 
       raise_application_error(-20001, 'title is of wrong type, please correct.'); 
     END IF; 

     IF :new.pub_id != VARCHAR2 THEN 
       raise_application_error(-20001, 'pub id is of wrong type, please correct.'); 
     END IF; 

     IF :new.price != NUMBER THEN 
       raise_application_error(-20001, 'number is of wrong type, pleace correct.'); 
     END IF; 

     IF :new.advance != NUMBER THEN 
       raise_application_error(-20001, 'advance is of wrong type, please correct.'); 
     END IF; 

     IF :new.ytd_sales != NUMBER THEN 
       raise_application_error(-20001, 'ytd sales is of wrong type, please correct.'); 
     END IF; 

     IF :new.pubdate is not DATE THEN 
       raise_application_error(-20001, 'pubdate is of wrong type, please correct.'); 
     END IF; 
     */ 

END; 
/
+0

创建存储过程以插入行并使用适当数据类型的参数。 –

+1

如果您尝试将任何内容插入到Oracle无法转换为数字的数字字段中,则会引发错误。任何数据类型都可以转换为varchar,所以这些检查也不是有用的。事实是,如果Oracle没有设法将输入转换为正确的数据类型,那么您将无法进入触发器来测试:NEW字段中的值。根据定义,它们必须是可浇注的才能存储到字段数据类型中。现在 - 如果您有特定的格式,那完全是另一个问题。 –

+0

我知道它会给我带来错误。但这是我们得到的任务...这是给我们一些触发器的练习。我们也必须做空检查,但我已经覆盖了。 –

回答

1

正如我在评论中提到,甲骨文将试图硬塞进一个varchar成若干对你的情况的照顾。但是,例如,您可以通过尝试将其转换为数字来验证varchar并非完全数字,并且如果成功则会引发错误。要做到这一点,你使用嵌套的BEGIN..EXCEPTION..END块。

CREATE OR REPLACE TRIGGER before_insert_book 
BEFORE INSERT ON book 
     FOR EACH ROW 
    nmbr_chk number; 
BEGIN 
     IF :new.ISBN is NULL THEN 
       raise_application_error(-20000, 'ISBN is null, insert was not accepted. Please revise your insert statement'); 
     END IF; 
     IF :new.title is NULL THEN 
       raise_application_error(-20000, 'TITLE is null, insert was not accepted. Please revise your insert statement'); 
     END IF; 

     BEGIN 
       nmbr_chk := to_number(:new.isbn); 
       -- if we got here we succeeded and ISBN is numeric, so fail 
       raise_application_error(-20001, 'isbn is of wrong type, please correct.'); 
     EXCEPTION 
      WHEN value_error 
      THEN 
        -- great, its not a number so continue. 
        NULL; 
     END; 
END; 
/
+0

这看起来很有希望,现在就试用它。 –

+0

请注意,我只专门处理VALUE_ERROR异常,否则您将陷阱并忽略在块内引发的-20001。有些事情要小心,如果你曾经尝试过像WHEN OTHERS这样的快捷方式... –

0

这可以在没有触发的情况下完成。触发器非常强大,但只有在不能以更简单的方式完成工作时才能使用。

修改您的表以约束所有必须具有值的值具有NOT NULL约束的约束。

ALTER TABLE mytable 
ADD CONSTRAINT your_constraint_name_here CHECK(mynumber IS NOT NULL) ; 

Oracle会为你做你的类型检查。你不需要检查他们是否将一个字符串放入数字中。这会引发异常。你可以在正在推动这个的应用程序中捕捉到。

应用业务逻辑的存储过程始终是一个好主意,因为它将逻辑放在一个地方。

  • 易于维护
  • 重用
+0

我知道它可以用约束来完成。但这是我们给的任务。我需要知道如何在插入或更新之前使用触发器来执行此操作。 –