[英]Oracle SQL trigger on update issue - Study / learnings
I have created a copy of an existing database (I_Customer) with the below code: 我已使用以下代码创建了现有数据库(I_Customer)的副本:
CREATE TABLE N_CUSTOMER AS SELECT * FROM I_CUSTOMER;
I have created the below table that will act as a log for modifications to the N_Customer table: 我创建了下表,该表将用作修改N_Customer表的日志:
CREATE TABLE CUSTOMER_CHANGELOG
( cust_no NUMBER(5),
cust_name VARCHAR2(20),
contact VARCHAR2(20),
log_date DATE);
I have also created (with help from a stack member) the below trigger that will fire after the N_Customer table is edited and write some specific fields (new and old) tot he Customer_Changelog table: 我还创建了(在堆栈成员的帮助下)以下触发器,该触发器将在编辑N_Customer表并向Customer_Changelog表中写入一些特定字段(新的和旧的)后触发:
CREATE OR REPLACE
TRIGGER customer_up_tr
AFTER UPDATE ON n_customer
FOR EACH ROW
WHEN (OLD.contact <> 1 AND NEW.contact = 1 OR OLD.cust_name <> 1 AND NEW.cust_name = 1)
BEGIN
INSERT INTO customer_changelog (cust_no, cust_name, contact, log_date) VALUES (:OLD.cust_no, :OLD.cust_name, :OLD.contact, sysdate);
INSERT INTO customer_changelog (cust_no, cust_name, contact, log_date) VALUES (:NEW.cust_no, :NEW.cust_name, :NEW.contact, sysdate);
END;
Now when I use the below code to edit the N_Customer table: 现在,当我使用以下代码编辑N_Customer表时:
UPDATE N_CUSTOMER
SET cust_name = 'Peter Davis', contact = 'Sam Bogdanovich'
WHERE cust_no = 2338;
I get this error: 我收到此错误:
UPDATE N_CUSTOMER
*
ERROR at line 1:
ORA-01722: invalid number
Now my data types etc all match so I am not sure what could be causing this. 现在我的数据类型等都匹配了,所以我不确定是什么原因造成的。
Any ideas would be much appreciated. 任何想法将不胜感激。
The problem is in this line of the trigger: 问题出在触发器的这一行:
(OLD.contact <> 1 AND NEW.contact = 1 OR OLD.cust_name <> 1 AND NEW.cust_name = 1)
Contact and cust_name fields are VARCHAR2, but the trigger is comparing them to a number. Contact和cust_name字段是VARCHAR2,但是触发器正在将它们与数字进行比较。
This simple example will fail with the same error: 这个简单的示例将因相同的错误而失败:
SELECT 1 FROM DUAL
WHERE 'abc' <> 1;
The expression OLD.contact <> 1
is comparing the character column contact
to a number (This is also known as "comparing apples to oranges"). 表达式
OLD.contact <> 1
字符列的contact
与一个数字进行比较(这也称为“将苹果与橙子进行比较”)。
Because the conversion of a number to a character is ambigous (it could be converted to '01',
'001' ...) Oracle will do it the other way round and convert the character value to a number (because that is non-amgigous
'01' ,
'001' will both result in the number
1`). 由于将数字转换为字符非常困难(可以将其转换为
'01',
'001' ...) Oracle will do it the other way round and convert the character value to a number (because that is non-amgigous
'01' ,
'001' will both result in the number
1`)。
You apparently have non-numeric values in the contact
column (which is to be expected based on the column's name and it's data type) the conversion fails. 显然,
contact
列中有非数字值(根据列名及其数据类型,这是预期值),转换将失败。
The simple rule is: 简单的规则是:
Use character literals for characters and number literals for numbers. 使用字符文字表示数字,使用数字文字表示数字。
1
is a number. 1
是数字。 '1'
is a character literal. '1'
是字符文字。
Having said all that, you need to change this line: 说了这么多,您需要更改此行:
OLD.contact <> 1 AND NEW.contact = 1 OR OLD.cust_name <> 1 AND NEW.cust_name = 1
to 至
OLD.contact <> '1' AND NEW.contact = '1' OR OLD.cust_name <> '1' AND NEW.cust_name = '1'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.