2009-05-26 68 views
2

我想實現在MS SQL一種構造,看起來像這樣在甲骨文的PL/SQL:的Transact-SQL:插入XYZ(從ABC選擇*)

declare 
asdf number; 
begin 
for r in (select * from xyz) loop 
    insert into abc (column1, column2, column3) 
    values (r.asdf, r.vcxvc, r.dffgdfg) returning id into asdf; 

    update xyz set column10 = asdf where ID = r.ID; 
end loop; 
end; 

任何想法如何實現這一會有幫助。

在此先感謝

+0

戴維斯,請考慮使用遊標,你不應該,如果在所有可能使用SQL Server遊標,因爲它們相比非常緩慢,基於集合的解決方案。提供了基於集合的解決方案,您應該考慮它們。即使您正在從Oracle轉換,您也需要停止思考循環,並在使用SQL Server時開始思考數據集的間歇性。 – HLGEM 2009-05-26 14:42:57

回答

2
declare @asdf int/varchar -- unsure of datatype 
declare @vcxvcint/varchar -- unsure of datatype 
declare @dffgdfg int/varchar -- unsure of datatype 
declare @id int  
declare db_cursor CURSOR FOR SELECT asdf, vcxvc, dffgdfg FROM xyz 

OPEN db_cursor 
FETCH NEXT FROM db_cursor 
INTO @asdf, @vcxvcint, @dffgdfg 

WHILE @@FETCH_STATUS = 0 
BEGIN  
    insert into abc (column1, column2, column3) values (@asdf, @vcxvcint, @vcxvcint)  
    set @id = scope_identity() -- This will get the auto generated ID of the last inserted row 
    update xyz set column10 = @asdf where id = @  
    FETCH NEXT FROM db_cursor INTO @name  
END 

CLOSE db_cursor 
DEALLOCATE db_cursor 

當然基本上所有的DBA都會殺了你,如果你嘗試並將光標潛入生產代碼。

+0

DBA爲什麼會因遊標而變得不適? – Andomar 2009-05-26 07:56:05

+1

因爲遊標是性能殺手,應該用基於集合的代碼替換。我知道這在Oracle中並非如此,但它在SQL Server中。 – HLGEM 2009-05-26 14:39:45

6

這似乎只是一個表的副本,對吧?

好:

SELECT column1, column2, column3 INTO abc FROM xyz 

我想你也能以類似

INSERT INTO abc SELECT column1, column2, column3 FROM xyz 

但在你需要之前創建表的第二種情況,第一,而不是不還創建表

Cheers Johannes

3

無光標版本,但與temp欄:

-- //temporarily add the column (assume the table "abc" already exists) 
ALTER TABLE "abc" ADD xyzID INT; 
GO; 
-- //insert all the data (assuming the ID field on "xyz" is called ID) 
INSERT INTO "abc" (column1, column2, column3, xyzID) SELECT asdf, vcxvc, rdffgdfg, ID FROM "xyz"; 
-- //update "xyd" with the new ID 
UPDATE "xyd" SET column10 = "abc".ID FROM "xyd" INNER JOIN "abc" ON "xyd".ID = "abc".xydID 
-- //drop the temporary column 
ALTER TABLE "abc" DROP COLUMN xyzID; 
1

如果我明白你問(我不精通PL/SQL),看起來像一個非常簡單的任務:

INSERT INTO abc(column1, column2, column3) SELECT asdf, vcxvc, dffgdfg FROM xyz; 
UPDATE xyz SET column10 = id; 

但我只是猜測你的意圖,希望沒有誤解。

PS:作爲someelse已經指出的那樣,你必須已經創建表ABC

0

希望這是你在找什麼:

declare 
asdf number; 
begin 
for r in (select * from xyz) loop 
    insert into abc (column1, column2, column3) 
    values (r.asdf, r.vcxvc, r.dffgdfg) returning id into asdf; 

    update xyz set column10 = asdf where ID = r.ID; 
end loop; 
end; 

將成爲

DECLARE @asdf int 
DECLARE @ID int 
DECLARE @MyTmpTableVar table(asdf int, abc_id int) 

// insert records from your cursor r into table abc, 
// and return a temporary table with "id" and "asdf" fields from the xyz table 
INSERT INTO abc(column1, column2, column3) 
OUTPUT asdf, id INTO @MyTmpTableVar 
SELECT r.asdf, r.vcxvc, r.dffgdfg 
FROM xyz 

// if it would return just one row and you wanted to find the value 
//SELECT @asdf = asdf, @id = abc_id 
//FROM @MyTmpTableVar 

// update the table xyz with the values stored in temporary table 
// restricting by the key "id" 
UPDATE xyz 
SET xyz.column10 = t.asdf 
FROM @MyTmpTableVar AS t 
WHERE xyz.id = t.abc_id 

sqlserver版本的在Oracle中返回子句OUTPUT子句。

請訪問this msdn page的完整信息,