2011-11-05 57 views
3

在我的應用程序中,我有大量需要插入數據庫的數量(100+)的行。一旦他們被插入到數據庫中,我需要插入他們的孩子,這些孩子有一個外鍵引用給孩子。如何使用Table-Valued參數插入多行然後返回它們的ID?

我想知道是否有辦法編寫一個存儲過程,可以插入所有這些行並將其ID返回給我的應用程序?

+0

這有一個壞計劃的氣味。爲什麼這樣,你認爲它會更快?只是一個一個地做 - 少問題恕我直言http://stackoverflow.com/questions/312003/what-is-the-mostridiculous-pessimization-youve-seen – Hogan

+0

@霍根 - 這實際上是一個非常好的優化。單個數據庫調用的性能將遠高於100。瀏覽網絡非常昂貴。 – Oded

+0

@Oded - 他仍然需要爲每個孩子打個電話;把父母和孩子交給一個SP並打100個電話而不是101個電話會更好嗎?該計劃還可以減少網絡流量 - 不需要將ID傳遞迴邏輯層。 – Hogan

回答

3

您已使用表值參數標記了您的問題 - 您可以將其中一個傳遞給存儲過程以插入數據庫。

可以使用OUTPUT子句和INSERTED邏輯表獲取新的ID值,並從存儲過程返回這些值。

3

下面是使用output子句的示例,如Oded建議的。首先,一些設置代碼:

if exists (select * from tempdb.sys.tables where name like '#tmp%') 
    drop table #tmp 
create table #tmp (id int identity, FirstName varchar(50), LastName varchar(50)) 

if exists (select * from sys.procedures where name = 'TestProcedure') 
    drop procedure TestProcedure 
if exists (select * from sys.types where name = 'TestTableType') 
    drop type TestTableType 

create type TestTableType as table (FirstName varchar(50), LastName varchar(50)) 
go 

現在,我們可以創建存儲過程:

create procedure dbo.TestProcedure 
    @List TestTableType readonly 
as 
insert #tmp 
     (FirstName, LastName) 
output inserted.* 
select FirstName 
,  LastName 
from @List l 
go 

注意output子句,它告訴SQL Server返回插入的行返回給客戶端,其中包括價值的身份專欄。既然代碼設置完畢,我們可以測試它:

declare @List TestTableType 
insert @List values ('Rick','Cain'), 
    ('Herman', 'Gingrich'), 
    ('Newt', 'Paul'), 
    ('Ron', 'Perry') 

exec dbo.TestProcedure @List 

select * from #tmp 

你會看到,由過程返回的值#tmp匹配值完全相同。

0

我我仍然在研究如何做到這一點,但在我看來,如果你想插入一個父表和一個子表,可以用一個SQL調用通過將兩個表作爲表值參數來完成。如果你有一些人爲的同一性(關係),它當前將兩個表連接成一個行號,但並不是必要地存儲在任何數據庫表中,那麼當插入父級並獲取其身份值時,它可以連接到子表使用獨特的關係和孩子的外鍵可以更新。然後可以插入孩子。

輸出很有意思,但我實際上並不需要輸出,它只是在sproc中使用,所以我必須做更多的研究以查看輸出是否可以被使用,例如輸出它到一個臨時表。

回答我的問題對於輸出語法是:

[ OUTPUT <dml_select_list> INTO { @table_variable | output_table } [ (column_list) ] ] 

,因此它可以被用來創建一個加入了與兒童的臨時表。

+0

你應該問一個新問題並自己回答 – j0k

相關問題