CREATE PROCEDURE p_processDataFor @accountId
BEGIN
for each item in
(select * from Accounts where accountId = @accountId and isProcessed = 0)
BEGIN
CASE current row
WHEN has x Condition THEN
exec p_x <Pass all data of current row>
WHEN has y Condition THEN
exec p_y <Pass all data of current row>
WHEN has z Condition THEN
exec p_z <Pass all data of current row>
END
END
END
回答
好吧,這個例子中只做了條件X1的插入,但希望顯示您可以進行的方式:
create table T1 (
ID int IDENTITY(1,1) not null,
Val1 varchar(10) not null,
constraint PK_T1 PRIMARY KEY (ID)
)
go
create table T2 (
ID int not null,
Val2 varchar(10) not null,
constraint PK_T2 PRIMARY KEY (ID)
)
go
create table Val (
ID int IDENTITY(1,1) not null,
Val1 varchar(10) not null,
Val2 varchar(10) not null,
Processed bit not null,
CondX bit not null
)
go
瓦爾是包含行要處理我的表(在你的榜樣,帳戶) 。 T1和T2是目前插入到/更新您的p_x
過程的兩個表。
insert into Val(Val1,Val2,Processed,CondX)
select 'abc','def',0,1 union all
select 'ghi','jkl',0,0 union all
select 'mno','pqr',0,1
go
只是一些樣本數據 - 我有3排,其中2相匹配「條件X」:
declare @Inter table (ValID int,T1ID int,Val2 varchar(10))
;merge into T1 using (select * from Val where CondX=1) Val on 1=0
when not matched then insert (Val1) values (Val.Val1)
output inserted.ID,Val.ID,Val.Val2 into @Inter (T1ID,ValID,Val2);
insert into T2(ID,Val2)
select T1ID,Val2 from @Inter
update Val set Processed = 1 where ID in (select ValID from @Inter)
go
爲了您的實際工作中,你會希望上述3份 - 一個用於x,y和z中的每一個。如果它位於相同的存儲過程中,則需要爲@Inter表使用不同的名稱。 merge statement被略微濫用,因爲您不能使用引用insert語句中的其他表的OUTPUT clause。但是我們正在使用它來捕獲T1中生成的IDENTITY值以及將要插入到其他表中的相應數據。
所以現在我們將使用表變量@Inter
進一步插入到T2中,並最終更新Val以指示行已經被處理。如果存在需要插入和獲取標識值的錶鏈,則需要引入更多合併語句和表變量。
select * from Val
select * from T1
select * from T2
而我們得到我們的結果:
ID Val1 Val2 Processed CondX
----------- ---------- ---------- --------- -----
1 abc def 1 1
2 ghi jkl 0 0
3 mno pqr 1 1
(3 row(s) affected)
ID Val1
----------- ----------
1 abc
2 mno
(2 row(s) affected)
ID Val2
----------- ----------
1 def
2 pqr
(2 row(s) affected)
因此,我們執行的所有我們的條件X1的工作,保持整個基礎代碼集。
由於您正在調用EXEC,因此無法正常執行循環操作,因此無法將其作爲基於SET的操作完成;它必須一個接一個地完成。
如果你只是想避免一般的CURSOR,你可以使用WHILE循環來實現它。
否則,另一個選擇是使用SELECT + FOR XML語句,該語句將EXEC語句構建爲一個NVARCHAR(MAX)語句到一個變量中,然後EXEC就是該動態SQL。
+1請問您可以告訴我如何使用SELECT + FOR XML來獲取單個nvarchar(max)值? – IsmailS 2011-03-18 10:11:21
- 1. 避免使用SQL中的遊標
- 2. 如何避免sql server中的遊標?也想避免while循環
- 3. Java - 如何避免此重複代碼
- 4. 如何避免此代碼中的GOTO
- 5. 如何實現此代碼?
- 6. 如何使用此代碼實現globalToLocal?
- 7. 如何將此代碼分解以避免C#代碼重複?
- 8. 避免重複SQL代碼?
- 9. 此代碼的僞代碼
- 10. 如何避免此
- 11. 避免使用遊標的ANR
- 12. 如何通過使用LINQ來避免循環以下代碼?
- 13. 如何在使用遊標時避免在T-SQL中重複使用FETCH?
- 14. 如何避免遊標問題?
- 15. 如何避免重複使用與接口相同的實現代碼?
- 16. SQL Server批量更新避免光標
- 17. SQL Server中避免數據庫光標
- 18. SQL Server存儲過程避免光標
- 19. PHP代碼,以避免SQL注入
- 20. 如何避免SQL Server上雙
- 21. 如何避免約束SQL Server 2008
- 22. 如何在atmega32上實現此代碼
- 23. 如何在此代碼中實現AsyncTask。
- 24. SQL Server等效於使用JOIN來避免重複的列
- 25. 如何實現使用()在SQL Server
- 26. 如何避免此java.lang.NullPointerException?
- 27. 避免在此代碼中使用活動頁面
- 28. 避免在插入SQL SERVER
- 29. 避免重複行SQL Server
- 30. 如何合併此代碼以避免多個#temp表寫入?
您可能需要內嵌「p_x」,「p_y」和「p_z」的內容。沒有看到它們的內容,在這種情況下很難知道這是否可能。知道是否在系統的其他地方使用了「p_x」等也是有用的。 – 2011-03-18 08:11:38
p_x等包含的代碼將基於少數條件將數據插入到其他表中。假設p_x等不會在其他地方使用。 – IsmailS 2011-03-18 10:06:15
一行會匹配多個x,y和/或z條件,並且是您達到的所期望的行爲(如果x條件匹配,則永遠不會考慮y或z)。另外,這個遊標從未設置的事實是否被處理爲另一個值或遺漏,或者在別處處理過(或與它無關)? – 2011-03-18 10:12:40