Rev*_*les 7 sql t-sql sql-server sql-server-2008
我甚至不确定如何说出这个问题但是这里有.我需要能够在同一个SQL脚本中循环遍历结果集,并在更多SQL中使用结果.
例如
begin
SELECT (SELECT ColumnA, ColumnB from SomeTable) as x
loop through x(
INSERT ColumnA into TableA
INSERT ColumnB into TableB
)
end
Run Code Online (Sandbox Code Playgroud)
但我忘了这样做的确切方法.我知道我之前在以前的位置上已经完成了,但我找不到该公司文件中的代码.
显然,这是一个非常粗略和基本的例子,我计划用结果集做更多的事情,但我只是以此为例.
编辑:这是一个更接近我想要做的事情的例子,如果这将有所帮助.
begin
while(select columnA, columnB, columnC, columnD from myTable) as x
begin
INSERT columnA, columnB into TableA
(get newly created ID of TableA - but that's a separate question involving @@IDENTITY)
INSERT NewID, columnC, columnD into TableB
end loop
end
Run Code Online (Sandbox Code Playgroud)
Gio*_*uri 15
在SQL它被称为CURSORS.基本结构CURSOR是:
DECLARE @ColumnA INT, @ColumnB INT
DECLARE CurName CURSOR FAST_FORWARD READ_ONLY
FOR
SELECT ColumnA, ColumnB
FROM SomeTable
OPEN CurName
FETCH NEXT FROM CurName INTO @ColumnA, @ColumnB
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO TableA( ColumnA )
VALUES ( @ColumnA )
INSERT INTO TableB( ColumnB )
VALUES ( @ColumnB )
FETCH NEXT FROM CurName INTO @ColumnA, @ColumnB
END
CLOSE CurName
DEALLOCATE CurName
Run Code Online (Sandbox Code Playgroud)
迭代解决方案的另一种方式是WHILE循环.但要使其工作,您应该在表中具有唯一的标识列.例如
DECLARE @id INT
SELECT TOP 1 @id = id FROM dbo.Orders ORDER BY ID
WHILE @id IS NOT NULL
BEGIN
PRINT @id
SELECT TOP 1 @id = id FROM dbo.Orders WHERE ID > @id ORDER BY ID
IF @@ROWCOUNT = 0
BREAK
END
Run Code Online (Sandbox Code Playgroud)
但请注意,CURSORS如果有替代方法而不是迭代方式执行相同的工作,则应该避免使用.但当然有一种情况是你无法避免的CURSORs
处理以基于集合的方式获取身份的常用方法是通过以下OUTPUT条款:
INSERT INTO TableA (ColumnA, ColumnB)
OUTPUT inserted.Id, inserted.ColumnA, inserted.ColumnB
SELECT ColumnA, ColumnB
FROM MyTable;
Run Code Online (Sandbox Code Playgroud)
这里的问题是你理想的做法是:
INSERT INTO TableA (ColumnA, ColumnB)
OUTPUT inserted.Id, MyTable.ColumnC, inserted.ColumnD
INTO TableB (AID, ColumnC, ColumnD)
SELECT ColumnA, ColumnB
FROM MyTable;
Run Code Online (Sandbox Code Playgroud)
问题是您无法在OUTPUT中引用源表,只能引用目标.幸运的是有一个解决方法MERGE,因为这允许你使用引用驻留内存插入表和输出子句中的源表,如果你使用MERGE永远不会是真的条件你可以输出所有列你需要:
WITH x AS
( SELECT ColumnA, ColumnB, ColumnC, ColumnD
FROM MyTable
)
MERGE INTO TableA AS a
USING x
ON 1 = 0 -- USE A CLAUSE THAT WILL NEVER BE TRUE
WHEN NOT MATCHED THEN
INSERT (ColumnA, ColumnB)
VALUES (x.ColumnA, x.ColumnB)
OUTPUT inserted.ID, x.ColumnC, x.ColumnD INTO TableB (NewID, ColumnC, ColumnD);
Run Code Online (Sandbox Code Playgroud)
此方法的问题是SQL Server不允许您插入外键关系的任何一侧,因此如果tableB.NewID引用tableA.ID,则上述操作将失败.要解决此问题,您需要输出到临时表,然后将临时表插入TableB:
CREATE TABLE #Temp (AID INT, ColumnC INT, ColumnD INT);
WITH x AS
( SELECT ColumnA, ColumnB, ColumnC, ColumnD
FROM MyTable
)
MERGE INTO TableA AS a
USING x
ON 1 = 0 -- USE A CLAUSE THAT WILL NEVER BE TRUE
WHEN NOT MATCHED THEN
INSERT (ColumnA, ColumnB)
VALUES (x.ColumnA, x.ColumnB)
OUTPUT inserted.ID, x.ColumnC, x.ColumnD INTO #Temp (AID, ColumnC, ColumnD);
INSERT TableB (AID, ColumnC, ColumnD)
SELECT AID, ColumnC, ColumnD
FROM #Temp;
Run Code Online (Sandbox Code Playgroud)