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