Dom*_*fer 13 sql t-sql sql-server
是否有可能以某种方式为select的每一行执行一些代码而不使用游标?
在我的情况下:我有一个临时表来存储一个复杂脚本的数据.最后,我想在输出中提示该表的某些信息(受某些条件限制).
目前我正在使用带有select的游标来限制表的行.在这个游标我正在使用
print '...'
Run Code Online (Sandbox Code Playgroud)
生成输出.
必须有一种更简单的方法来做这些事情......
编辑:
create table #tmpAttributes(AttributeId uniqueidentifier, Value float, ValueString nvarchar(max), ActionId uniqueidentifier)
insert into #tmpAttributes (AttributeId, Value, ValueString, ActionId)
select ID,..... -- in this select i'm doing some value conversions, if conversion is not possible i'm using -1
insert into ActionAttribute (ActionDefinitionID, Discriminator, ID, ReferredActionID, ValueDate, ValueListID, ValueMoney, ValueString, ValueUserID)
select @defId, 'ActionAttributeMoneyEntity', NEWID(), ActionId, null, null, Value, null, null from #tmpAttributes
-- afterwards there is this cursor where I'm printint all rows where Value = -1
Run Code Online (Sandbox Code Playgroud)
Gar*_*ker 20
对结果集中的每一行执行print语句几乎需要一个游标或类似于此的方法
declare @id int, @stuff varchar(20)
declare @tmp table
(
id int not null
, stuff varchar(20)
primary key(id)
)
insert @tmp
select id, stuff from mastertable
where condition1 > condition2
select top 1 @id=id, @stuff=stuff from @tmp
while (@@rowcount > 0)
begin
print @stuff
delete from @tmp where id=@id
select top 1 @id=id, @stuff=stuff from @tmp
end
Run Code Online (Sandbox Code Playgroud)
你仍然在每行循环,但你避免使用光标.由于您使用表var而不是游标,因此可以避免表锁定,但这不一定是更好的方法.您可以通过各种可能的方式逐行处理,例如添加"已处理的列"或对所有选定的行进行编号1..n并根据rownumber进行迭代
如果可以执行基于集合的操作,则只能逐行处理.您的问题中没有足够的信息来查看TSQL中是否可以避免这种情况
现在,编写CLR proc可能会更灵活,因为您拥有更丰富的编程模型,并且在CLR proc中循环遍历结果集的每一行的开销很小.对于数据库从TSQL中的每一行调用的每一行,从CLR proc进行数据库调用
EDIT - I see someone already added one possible way to convert you print statements into a set oriented operation. i.e.
declare @msg varchar(max)
select @msg = ''
select msg = @msg + stuff
from mastertable where condition1 > condition2
print @msg
Run Code Online (Sandbox Code Playgroud)
This is OK, in fact optimal what I was referring to when I said performing a set operation. A set based operation is always preferred when possible . It may not be obvious, but string concatenation can also get very slow in this example too if many rows are involved.
I said that using a temp var avoids table locking. This is not precisely true as sql server does write temp vars to a table in tempdb. What I really meant was that you avoid locking a production table and since you are guaranteed to be the only user of this table, you don't compete for concurrent access.
I also made no attempt to make optimize this. For example, the inner loop could track the id and the where condition becomes where id>@id (you will also want a primary key defined on id). Since the temp table is not updated during each loop iteration I would expect it to be faster.
我认为你需要提供更多细节,但你可能正在寻找类似的东西:
declare @msg varchar(max)='';
select @msg = @msg + 'Output line: ' + ColumnA + ' -- ' + 'ColumnB' + char(13)+char(10)
from #temp
where ...
;
print @msg;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
48576 次 |
最近记录: |