我需要在某些表中插入一定数量的行,并从变量中获取值。我当然可以一次插入一行循环,但这太简单了。我正在寻找更优雅的解决方案。我目前的想法是围绕INSERT INTO ... SELECT ...
语句,但现在我需要一个查询来生成我需要的行数。我试着写递归CTE来做到这一点:
CREATE FUNCTION ufGenerateRows(@numRows INT = 1)
RETURNS @RtnValue TABLE
(
RowID INT NOT NULL
)
AS
BEGIN
WITH numbers AS
(
SELECT 1 as N
UNION ALL
SELECT N + 1
FROM numbers
WHERE N + 1 <= @numRows
)
INSERT INTO @RtnValue
SELECT N
FROM numbers
RETURN
END
GO
它有效,但递归深度限制为100,这对我来说不合适。你能建议替代方案吗?
答案 0 :(得分:3)
dbo.
架构前缀,尤其是函数。递归CTE是生成集合的最低效方法(更好的示例见这个由三部分组成的系列):
以下是一个例子:
CREATE FUNCTION dbo.GenerateRows(@numRows INT = 1)
RETURNS TABLE
AS
RETURN
(
SELECT TOP (@numRows) RowID = ROW_NUMBER() OVER (ORDER BY s1.[number])
FROM master.dbo.spt_values AS s1
-- CROSS JOIN master.dbo.spt_values AS s2
ORDER BY s1.[number]
);
如果您需要超过2,500行,您可以与自己或其他表交叉连接。
更好的方法是创建自己的数字表(再次,请参阅上面的链接以获取示例)。
答案 1 :(得分:1)
不要反复思考 - 循环 - 但是基于集合 - 一次性完成。
INSERT INTO
... SELECT TOP
x
...应该做你需要的而不重复插入。
当我没有绑定到手机时,我会跟着一个例子。
更新:
@AaronBertrand说的是什么。 :} CROSS JOIN
中的SELECT
是正确的。