带有sp_executesql和参数的游标

时间:2017-03-01 08:10:41

标签: sql sql-server sql-server-2008 tsql sql-server-2014

我希望对我一直在努力解决的问题提供一些进一步的帮助,我昨天发布了一个类似的问题,但我认为我使用的例子是复杂的我想要的所以我决定从头开始写我自己的。

如前所述,我有一个包含许多sql语句的表,我希望依次运行每个语句并使用结果以及运行代码的时间更新同一个表。到目前为止,我的代码遍历每个SQL语句并执行它但是我找不到一种方法来更新Last_Result并执行每个单独的select语句,即将值输出到参数,例如: @retval OUTPUT甚至如何将它存储在带有ID的临时表中,以便稍后我可以单独更新 从学习的角度来看,了解如何使用@retval OUTPUT设置参数以及如何直接更新表格会很好。 任何人都可以对我现在出错的地方有所了解。现在他们已经绝望了。

  CREATE TABLE [dbo].[Test_Run](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](250) NULL,
    [Script] [nvarchar](max) NULL,
    [Last_Result] [nvarchar](100) NULL,
    [Last_Runtime] [datetime] NULL
CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

declare @cursor nvarchar(4000)

set @cursor = 

'declare c_tables cursor fast_forward for 

select distinct
    ID,
    Name,
    Script
from Test_Run 
order by ID asc
'

exec sp_executesql @cursor

open c_tables 

    declare @ID varchar(2),
            @Name varchar(35),
            @Scripts nvarchar(3000),
            @Result as varchar(10),
            @ParmDefinition nvarchar(500),
            @retval as varchar(10) 

SET @ParmDefinition = N'@retvalOUT int OUTPUT';

fetch next from c_tables into @ID, @Name, @Scripts

while @@fetch_status = 0 

begin 

-- insert into Test_Run(Last_Result)
 exec sp_executesql @Scripts, N'@ID',@ID;--,@ParmDefinition, @retvalOUT=@retval OUTPUT;

-- select @retval
fetch next from c_tables into @ID, @Name, @Scripts

end 

close c_tables 
deallocate c_tables 

3 个答案:

答案 0 :(得分:2)

我认为这样做(这里是live demo):

declare 
    @id int, 
    @sql nvarchar(max), 
    @last_result nvarchar(100), 
    @last_runtime datetime,
    @params nvarchar(max);

SET @params = N'@retvalOUT varchar(max) OUTPUT';


select @id = min(id) from Test_Run;
while @id is not null
begin
    select @sql = Script from Test_Run where id = @id;
    set @sql = 'select @retvalOUT= (' + @sql + ')';
    exec sp_executesql @sql, @params, @retvalOUT = @last_result OUTPUT;
    set @last_runtime = getdate();

    update Test_Run set Last_Result = @last_result, Last_Runtime = @last_runtime where id = @id;

    select @id = min(id) from Test_Run where id > @id;
end

我完全删除了光标并使用了while循环 - 我想我不太喜欢游标: - )

答案 1 :(得分:1)

首先,正常声明游标,因此不需要为它使用sp_executesql:

declare c_tables cursor fast_forward for 

select 
    ID,
    Name,
    Script
from Test_Run 
order by ID asc

请注意,我删除了distinct个关键字,我认为ID是候选键。

答案 2 :(得分:0)

sp_executesql运行的代码在其自己的范围内。在该范围内创建的任何变量和游标都不在外面。

在你的情况下,在exec sql作用域中创建c_tables,因此open语句不存在。{/ p>