create table tab3(a integer,d1 datetime default getdate())
insert into tab3(a) values(1)
insert into tab3 (a) select a from tab3
GO 20
insert into tab3 (a) select a from tab3
select d1,count(*) from tab3(NOLOCK) group by d1
最后一次插入肯定需要很长的时间(在我的机器上3秒)
但是,d1
中的值每批次不同。即最终查询仅返回22行
2014-06-22 20:34:53.787 1
2014-06-22 20:34:56.127 1
2014-06-22 20:34:56.140 2
2014-06-22 20:34:56.153 4
2014-06-22 20:34:56.157 8
2014-06-22 20:34:56.160 16
2014-06-22 20:34:56.163 32
2014-06-22 20:34:56.167 64
2014-06-22 20:34:56.170 128
2014-06-22 20:34:56.177 256
2014-06-22 20:34:56.183 512
2014-06-22 20:34:56.193 1024
2014-06-22 20:34:56.210 2048
2014-06-22 20:34:56.240 4096
2014-06-22 20:34:56.293 8192
2014-06-22 20:34:56.397 16384
2014-06-22 20:34:56.493 32768
2014-06-22 20:34:56.607 65536
2014-06-22 20:34:56.817 131072
2014-06-22 20:34:57.240 262144
2014-06-22 20:34:57.710 524288
2014-06-22 20:35:01.630 1048576
为什么GETDATE()初始化每个语句而不是每个插入?
如何在不使用游标的情况下确保每行而不是每个语句初始化默认值?
编辑:可能相关,tab3_log与tab3具有相同的架构
CREATE TRIGGER tab3_logger on tab3
AFTER INSERT
AS
BEGIN
INSERT INTO tab3_log(a) select a from inserted
END
将单个insert语句中的所有行显示为具有相同的日期时间
答案 0 :(得分:4)
什么时候初始化默认值?
这取决于表达式是否为“runtime constant”。
要获得所需的行为,可以将调用包装在标量UDF中。
CREATE FUNCTION dbo.F()
RETURNS DATETIME
AS
BEGIN
RETURN GETDATE()
END
GO
CREATE TABLE T
(
A CHAR(8000) NULL,
B FLOAT DEFAULT RAND(),
C DATETIME DEFAULT GETDATE(),
D DATETIME DEFAULT dbo.F(),
E UNIQUEIDENTIFIER DEFAULT NEWID()
)
INSERT INTO T
(A)
SELECT TOP 100000 'A'
FROM master..spt_values v1,
master..spt_values v2
SELECT COUNT(DISTINCT B) AS B,
COUNT(DISTINCT C) AS C,
COUNT(DISTINCT D) AS D,
COUNT(DISTINCT E) AS E
FROM T
GO
DROP TABLE T;
DROP FUNCTION F;
返回(例如,D
的确切值会有所不同)
+---+---+-----+--------+
| B | C | D | E |
+---+---+-----+--------+
| 1 | 1 | 823 | 100000 |
+---+---+-----+--------+
每个语句评估前两个,每行第二个。
答案 1 :(得分:3)
SQL是基于集合的,而不是逐行的。 insert语句在逻辑上一次性发生,因此为语句插入的所有行分配相同的值是正确的。您甚至可以在更快的机器上获得不同语句的相同getdate值,因为getdate只有精度为毫秒,精度为正负3-4毫秒。
答案 2 :(得分:1)
为什么会发生这种情况很难说清楚。我认为这是优化与“列默认值”的语义之间的关系。也许SQL对此没有任何说法。但是有人可以说这个日期可以用于单笔交易。
不确定如何解决,但我会尝试这个:
insert into tab3 (a, d1) select a, getdate() from tab3
GO 20