在 SQL 中遍历 SELECT 个结果集
Looping through SELECT result set in SQL
我什至不确定如何表达这个问题,但就这样吧。我需要能够在同一个 SQL 脚本中遍历结果集,并在更多 SQL.
中使用结果
例如
begin
SELECT (SELECT ColumnA, ColumnB from SomeTable) as x
loop through x(
INSERT ColumnA into TableA
INSERT ColumnB into TableB
)
end
但是我忘记了具体的做法。我知道我以前在以前的职位上做过,但我无法在我那家公司的文件中找到它的代码。
显然,这是一个非常粗糙和基本的示例,我计划对结果集做更多的事情,但我只是举个例子。
编辑:这是我想要做的更详细的示例,以防这会有所帮助。
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
不要使用游标,因为它对性能不利。
试试这个 link:
http://support2.microsoft.com/kb/111401
您应该使用 ROW_NUMBER() 并将数据填充到临时数组 table - 变量或全局 table。
如果您只是将数据从一个 table 插入到另一个,您可以使用这种方法:
insert into TableA (ColumnA, ColumnB, myTableID)
select (ColumnA, ColumnB, myTableID) from myTable
insert into TableB (ColumnC, ColumnD, myTableID)
select m.ColumnC, m.ColumnD, a.TableAid
from myTable m
join TableA a
on m.myTableID = a.myTableID
编辑:
您可以在myTable
外键的TableA
中添加一列。这将帮助您在 TableB
.
中获取 TableA
的 ID
在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
另一种迭代求解的方法是WHILE
循环。但要使其正常工作,您应该在 table 中具有唯一标识列。例如
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
但是请注意,如果有替代方法而不是迭代方法来完成相同的工作,您应该避免使用 CURSORS
。但是当然有些情况是你无法避免的CURSORs
以基于集合的方式处理获取身份的常用方法是通过 OUTPUT
子句:
INSERT INTO TableA (ColumnA, ColumnB)
OUTPUT inserted.Id, inserted.ColumnA, inserted.ColumnB
SELECT ColumnA, ColumnB
FROM MyTable;
这里的问题是您最理想的做法是:
INSERT INTO TableA (ColumnA, ColumnB)
OUTPUT inserted.Id, MyTable.ColumnC, inserted.ColumnD
INTO TableB (AID, ColumnC, ColumnD)
SELECT ColumnA, ColumnB
FROM MyTable;
问题是您不能在输出中引用源 table,只能引用目标。幸运的是,使用 MERGE
可以解决此问题,因为这允许您在使用 [=15] 时同时引用插入的常驻内存 table 和输出子句中的源 table =] 在永远不会成立的条件下,您可以输出所需的所有列:
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);
此方法的问题是 SQL 服务器不允许您插入外键关系的任何一侧,因此如果 tableB.NewID 引用 tableA.ID 则上述操作将失败.要解决此问题,您需要输出到临时 table,然后将临时 table 插入 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;
我什至不确定如何表达这个问题,但就这样吧。我需要能够在同一个 SQL 脚本中遍历结果集,并在更多 SQL.
中使用结果例如
begin
SELECT (SELECT ColumnA, ColumnB from SomeTable) as x
loop through x(
INSERT ColumnA into TableA
INSERT ColumnB into TableB
)
end
但是我忘记了具体的做法。我知道我以前在以前的职位上做过,但我无法在我那家公司的文件中找到它的代码。
显然,这是一个非常粗糙和基本的示例,我计划对结果集做更多的事情,但我只是举个例子。
编辑:这是我想要做的更详细的示例,以防这会有所帮助。
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
不要使用游标,因为它对性能不利。
试试这个 link: http://support2.microsoft.com/kb/111401
您应该使用 ROW_NUMBER() 并将数据填充到临时数组 table - 变量或全局 table。
如果您只是将数据从一个 table 插入到另一个,您可以使用这种方法:
insert into TableA (ColumnA, ColumnB, myTableID)
select (ColumnA, ColumnB, myTableID) from myTable
insert into TableB (ColumnC, ColumnD, myTableID)
select m.ColumnC, m.ColumnD, a.TableAid
from myTable m
join TableA a
on m.myTableID = a.myTableID
编辑:
您可以在myTable
外键的TableA
中添加一列。这将帮助您在 TableB
.
TableA
的 ID
在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
另一种迭代求解的方法是WHILE
循环。但要使其正常工作,您应该在 table 中具有唯一标识列。例如
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
但是请注意,如果有替代方法而不是迭代方法来完成相同的工作,您应该避免使用 CURSORS
。但是当然有些情况是你无法避免的CURSORs
以基于集合的方式处理获取身份的常用方法是通过 OUTPUT
子句:
INSERT INTO TableA (ColumnA, ColumnB)
OUTPUT inserted.Id, inserted.ColumnA, inserted.ColumnB
SELECT ColumnA, ColumnB
FROM MyTable;
这里的问题是您最理想的做法是:
INSERT INTO TableA (ColumnA, ColumnB)
OUTPUT inserted.Id, MyTable.ColumnC, inserted.ColumnD
INTO TableB (AID, ColumnC, ColumnD)
SELECT ColumnA, ColumnB
FROM MyTable;
问题是您不能在输出中引用源 table,只能引用目标。幸运的是,使用 MERGE
可以解决此问题,因为这允许您在使用 [=15] 时同时引用插入的常驻内存 table 和输出子句中的源 table =] 在永远不会成立的条件下,您可以输出所需的所有列:
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);
此方法的问题是 SQL 服务器不允许您插入外键关系的任何一侧,因此如果 tableB.NewID 引用 tableA.ID 则上述操作将失败.要解决此问题,您需要输出到临时 table,然后将临时 table 插入 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;