在向现有表中插入新行时自动创建新GUID

时间:2019-02-15 20:44:06

标签: sql sql-server

我在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。是否可以通过触发器或功能?

2 个答案:

答案 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来解决它。

迟早,延迟编码会严格要求其价格。