SQL问题。插入前需要检查触发器的数据类型

时间:2015-10-26 17:14:12

标签: sql oracle triggers

我正在创建一个before insert和更新触发器之前检查数据类型。例如,我有一个ytd_sales字段,即NUMBER。我想创建一个触发器,如果​​有人尝试在这里插入一个varchar,则会输出错误信息。 我尝试过喜欢......

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;
/

2 个答案:

答案 0 :(得分:1)

正如我在评论中提到的那样,Oracle会处理尝试将varchar塞进一个数字的情况。但是,例如,您可以通过尝试将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;
/

答案 1 :(得分:0)

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

修改您的表,使其具有一个约束,即所有必须具有值的值都具有NOT NULL约束。

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

Oracle会为您进行类型检查。您无需检查是否将字符串放入数字中。这将抛出异常。你可以抓住推动这个的应用程序。

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

  • 更容易维护
  • 可重用性