如何向表中插入 N 行默认值

12

我有一张包含一个标识列和代表创建日期的列的表:

CREATE TABLE dbo.OrderStatus
(
    OrderStatusId int IDENTITY(1, 1) NOT NULL,
    CreationDate datetime NOT NULL default GETDATE(),
    CONSTRAINT PK_OrderStatus PRIMARY KEY(OrderStatusId)
)

由于标识列会自动生成值并且CreationDate始终是当前日期(GETDATE()),因此我可以通过DEFAULT VALUES添加一行:

INSERT INTO dbo.OrderStatus DEFAULT VALUES;

如果我想添加三个记录,该怎么办呢?

当前解决方案(已编辑一些输入,因为它没有任何意义)

目前为止,为了实现我的需求,我使用 VALUES 添加了多行:

INSERT INTO dbo.OrderStatus (CreationDate)
VALUES  (GETDATE()), 
        (GETDATE()), 
        (GETDATE())
虽然我更喜欢知道多行的INSERT INTO .. DEFAULT VALUES等价于什么,以防我以后添加一个具有默认值的列。
是否有一种方式可以使用DEFAULT VALUES或类似的方式将N行插入到表中?

通过移除默认的GETDATE()你能够实现什么? - Sagar
这里的目的是什么 - 为什么需要3个“默认”记录? - D Stanley
@Sagar 实际上,我对那个问题感到困扰。我没有取得任何成果。尽管如此,我仍然对多行的 INSERT INTO DEFAULT VALUES 等价物感兴趣。 - actaram
@DStanley 我知道这看起来很奇怪,但我想创建一个订单状态表,然后在订单状态表和语言表之间创建一个联接表,其中包含每个状态的翻译。因此,我已经知道现在我需要5个状态记录,然后管理员将能够从应用程序中添加额外的状态。 - actaram
@BishopBarber 是的,那似乎有点奇怪,但这可能会让您的工作更轻松- 您是否可以只添加与每种语言相关的记录,而不是“默认”记录? - D Stanley
@DStanley:每种语言的记录将添加到OrderStatusLang表(连接表)中。 OrderStatus表仅包含状态的基本信息。我之所以没有将所有内容放入一个表格中,是因为这样更容易创建一个过程,该过程将根据应用程序中选择的语言返回状态。 - actaram
4个回答

13

更简单的方法是:

insert dbo.OrderStatus default values
go 500

这将插入500行默认值。


我正在尝试在BEGIN...END块内进行插入。在这种情况下,是否有办法使用您的解决方案,还是必须坚持使用while循环? - actaram
4
"Go" 是 SSMS 命令,不是 SQL 或 TSQL 的一部分。这意味着您不能将其作为存储过程或脚本的一部分使用。 - benjamin moskovits
2
如果你只是在SSMS或SqlCmd中执行,这很容易。但你不能在存储过程或函数中使用它。 - Dan Field
@benjaminmoskovits,你能在你的回答中具体说明吗?这样对于新手来说可能更清晰,因为我的问题没有包括SSMS标签。 - actaram
当您在SQL Server Management Studio的查询窗口中工作时,您处于“SSMS”模式,并且可以使用Go。它由SSMS解释。如果您编写存储过程,则通常称为“proc”,当SQL Server引擎遇到GO时,可能会抛出错误。 - benjamin moskovits

12

您可以使用自己的定义,只需使用 while 循环即可。

DECLARE  @OrderStatus TABLE
(
    OrderStatusId int IDENTITY(1, 1) NOT NULL,
    CreationDate datetime NOT NULL DEFAULT GETDATE()
    --CONSTRAINT PK_OrderStatus PRIMARY KEY(OrderStatusId) -- this can be uncommented if creating a real table.
)


DECLARE @i int = 0;

WHILE @i < 100 -- insert 100 rows.  change this value to whatever you want.
BEGIN

INSERT @OrderStatus DEFAULT VALUES
SET @i = @i + 1;

END

SELECT * FROM @OrderStatus

以下是使用递归CTE的方法:

;with cteNums(n) AS
(
    SELECT 1
    UNION ALL
    SELECT n + 1
    FROM cteNums WHERE n < 100 -- how many times to iterate
)
INSERT @OrderStatus 
SELECT * FROM cteNums

请注意,对于CTE,如果指定的最大递归次数大于100,则必须指定OPTION(MAXRECURSION ...)。还要注意的是,即使从CTE中选择了数字列表,它们实际上也不会被插入到表中。


1

如果计数表足够大,Tally Table 方法可以插入大量的多行。这个 Tally 表最多可以处理1000个条目。

WITH Tally (n) AS
(
    -- 1000 rows
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
)
--SELECT * FROM Tally;

Create Table #temp (id int, d datetime, GUID uniqueidentifier, str1 nvarchar(1), number int)

insert into #temp
select n, getdate(), newid(), 'a', 101 from tally 
where N<=100 -- THIS IS WHERE YOU INDICATE HOW MANY ROWS

select * from #temp

-2

这种方法不够高效(递归),而且有些受限,总是需要添加相同数量的行,并且需要一个批列键来终止触发器循环。不过,创意加10分! - Jens Frandsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接