Mysql 更新问题上的Oracle SQL触发器-研究/学习

Mysql 更新问题上的Oracle SQL触发器-研究/学习,mysql,sql,oracle,plsql,triggers,Mysql,Sql,Oracle,Plsql,Triggers,我已使用以下代码创建了现有数据库(I_客户)的副本: CREATE TABLE N_CUSTOMER AS SELECT * FROM I_CUSTOMER; 我已经创建了下表,该表将用作N_Customer表修改的日志: CREATE TABLE CUSTOMER_CHANGELOG ( cust_no NUMBER(5), cust_name VARCHAR2(20), contact VARCHAR2(20), log_date DATE); UPDATE N_CUSTOMER SE

我已使用以下代码创建了现有数据库(I_客户)的副本:

CREATE TABLE N_CUSTOMER AS SELECT * FROM I_CUSTOMER;
我已经创建了下表,该表将用作N_Customer表修改的日志:

CREATE TABLE CUSTOMER_CHANGELOG 
( cust_no NUMBER(5),
cust_name VARCHAR2(20),
contact VARCHAR2(20),
log_date DATE);
UPDATE N_CUSTOMER
SET cust_name = 'Peter Davis', contact = 'Sam Bogdanovich'
WHERE cust_no = 2338;
我还创建了(在堆栈成员的帮助下)以下触发器,该触发器将在编辑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;
我得到这个错误:

UPDATE N_CUSTOMER
*
ERROR at line 1: 
ORA-01722: invalid number 
现在我的数据类型等都匹配,所以我不确定是什么原因导致了这种情况


任何想法都将不胜感激。

问题在于触发器的这一行:

(OLD.contact <> 1 AND NEW.contact = 1 OR OLD.cust_name <> 1 AND NEW.cust_name = 1)
(OLD.contact 1和NEW.contact=1或OLD.cust\u name 1和NEW.cust\u name=1)
Contact和cust_name字段是VARCHAR2,但触发器正在将它们与数字进行比较

此简单示例将失败,并出现相同的错误:

SELECT 1 FROM DUAL
WHERE 'abc' <> 1;
从双通道中选择1
其中“abc”1;

表达式
OLD.contact 1
将字符列
contact
与数字进行比较(这也称为“将苹果与桔子进行比较”)

因为数字到字符的转换是不明确的(它可以转换为
'01',
'001'
..),Oracle会反过来将字符值转换为数字(因为这是非对称的
'01'
'001'
都会产生数字
1`)

显然,
contact
列中有非数值(根据列的名称和数据类型,这是预期的),转换失败

简单的规则是:

永远不要依赖隐式类型转换 使用字符文字表示字符,数字文字表示数字
1
是一个数字<代码>'1'
是一个字符文本

说到这里,您需要更改这一行:

OLD.contact <> 1 AND NEW.contact = 1 OR OLD.cust_name <> 1 AND NEW.cust_name = 1
OLD.contact 1和NEW.contact=1或OLD.cust\u name 1和NEW.cust\u name=1

OLD.contact'1'和NEW.contact='1'或OLD.cust_name'1'和NEW.cust_name='1'

客户名称和联系人(在WHEN子句中使用)是否为数字?您好。不,他们是瓦查尔你好,肖恩。那么我真的要用abc替换1吗?没关系。我得到了它。如果我只是在{(OLD.contact 1和NEW.contact=1或OLD.cust_name 1和NEW.cust_name=1)}时删除,触发器会执行我需要的操作。
OLD.contact <> '1' AND NEW.contact = '1' OR OLD.cust_name <> '1' AND NEW.cust_name = '1'