我在MS SQL中有一个名为myTab的现有表。 它具有以下字段
empno(PK) nchar(10),
age int
现在,我想添加myGUID列并在每次插入新行以及更新现有行时用GUID填充它。
所以我添加了声明
ALTER TABLE myTab添加myGUID uniqueidentifier DEFAULT NewId()NOT NULL;
更新现有行可以正常工作。
但是,当我尝试插入值时,
插入myTab值(1000,22);
失败,并显示以下消息
**Column name or number of supplied values does not match table definition.**
当我这样做
插入sourav_test2值(20055711,23,NEWID());
以上陈述有效。
我希望在不更改插入语句的情况下填充GUID。是否可以通过触发器或功能?
答案 0 :(得分:6)
始终列出您要插入的列!
INSERT INTO myTab (empno, age)
VALUES ('1000', 22);
还要为值使用正确的类型。未提及的列将被为其指定默认值,如果没有明确的默认值,则被分配NULL
。
您的表有三列,因此,如果您忽略列列表,那么insert
会期望有三个值。如果需要,您仍然可以设置默认值,方法是在DEFAULT
子句中使用VALUES
关键字:
INSERT INTO myTab (empno, age, myGUID)
VALUES ('1000', 22, DEFAULT);
答案 1 :(得分:1)
Sourav关于触发器的问题让我开始思考,因此我尝试了一些测试。为什么?
想象一下这样一种情况,其中已经用数千个INSERT语句编写了应用程序,而这些语句不在列列表中。在这种情况下,如果您可以编写一个INSTEAD OF INSERT触发器来提供列列表,则可以希望自己避免由于添加了新列而更正了数千个INSERT语句。
我坦率地说,我不知道这是否行得通。
所以我写了这个小测试:
CREATE TABLE tt (ColA varchar(1));
INSERT INTO tt VALUES ('a');
ALTER TABLE tt
ADD ColB uniqueidentifier DEFAULT NEWID();
GO
CREATE TRIGGER tr_tt
ON tt
INSTEAD OF INSERT
AS
INSERT INTO tt (ColA)
SELECT ColA FROM inserted;
GO
INSERT INTO tt VALUES ('a');
SELECT * FROM tt;
DROP TABLE tt;
为了更全面,我还尝试了使用以下INSERT的TRIGGER的变体:
INSERT INTO tt (ColA, ColB)
SELECT ColA, NEWID() FROM inserted;
在两种情况下,结果都是相同的:与问题中报告的错误相同。所以要回答这个问题:
我们不能在这里使用可以做到的触发器吗?
答案是否定的。即使将INSTEAD OF INSERT TRIGGER放在表上,解析器仍然不会让您编写INSERT..VALUES()语句,除非VALUES的数量和顺序与表的定义完全匹配。不能使用TRIGGER来解决它。
迟早,延迟编码会严格要求其价格。