在sql存储过程中循环并删除游标
Posted
技术标签:
【中文标题】在sql存储过程中循环并删除游标【英文标题】:loop in sql stored procedure and removing cursors 【发布时间】:2015-05-26 23:25:17 【问题描述】:我必须修改由其他人编写的存储过程。基本上,存储过程使用游标从表中获取数据,然后将该数据插入另一个表中。在从另一个表中获取代码时,它还会从另一个表中获取一些不同的列下面是我的代码:
Declare data_cursor cursor for
Select emp_no, emp_name, event_date, Test_no, Code, Test_result
From test_table1
ORDER by emp_no
declare
@empNo varchar(100),
@emp_name varchar(2000),
@eventDate varchar(20),
@TestNo varchar(100),
@Code varchar(100),
@TestReuslt varchar(100),
@ProcessName varchar(100),
@FileProcess varchar(200),
@TestProcess varchar(100),
@countA int,
@error_count int
SELECT @ProcessName = (select distinct userID from test_table1)
SELECT @FileProcess = 'EW' + @ProcessName
Select @TestProcess = (Select distinct userID from test_Table1) + 'TXT'
select @countA = 0
BEGIN tran
OPEN data_cursor
fetch data_cursor into
@empNo ,
@emp_name ,
@eventDate ,
@TestNo ,
@Code ,
@TestReuslt
while (@@FETCH_STATUS=0)
begin
insert into TESTTable2
(
empNum, empName, eventDate,TestNum, Code, TestResult, Testprocess, ProcessName)
values (@empNo, @emp_name, @eventDate , @TestNo , @Code, @TestReuslt, @TestProcess, @ProcessName)
if @ ERROR > 0
begin
select @error_count = @error_count + 1
end
else
set @record_id = @@Identity
if @code like 'D%'
Insert into TESTTable3
(testProcess, FileProcess, empNum)
values (@TestProcess, @FileProcess, @empNo )
if @@error > 0
begin
select @error_count = @error_count + 1
end
set @countA = @countA + 1
fetch data_cursor into
fetch data_cursor into
@empNo ,
@emp_name ,
@eventDate ,
@TestNo ,
@Code ,
@TestReuslt
if @ ERROR > 0
BEGIN
select @error_count = @error_count + 1
end
end
if @error_count > 0
begin
rollback tran
end
else
begin /* @@error = 0 */
commit tran
close data_cursor
deallocate data_cursor
Insert into LOG_File
(Name, Count, Processname)
values ('Test1', @CountA,@ProcessName)
Select 'TotalCount' = @CountA
原因,我现在必须修改上面的存储过程是因为一些应用程序的变化,我从 test_table1 得到大约 50 个不同的用户 ID,所以上面的子查询(SELECT @ProcessName =(从 test_table1 中选择不同的用户 ID)没有工作。我怎样才能遍历上面存储的过程,以便每个@ProcessName 可以插入到表 TESTTable2 中,换句话说
我想一次传递每个 userId 并将其插入表 test_table1 和其他后续表中。我可以声明另一个游标来完成此操作,但我想知道是否有更好的方法来重写这个存储过程并且根本不使用游标。
由于我的应用程序更改,上面所有这三个语句都引发了错误:
SELECT @ProcessName = (select distinct userID from test_table1)
SELECT @FileProcess = 'EW' + @ProcessName
Select @TestProcess = (Select distinct userID from testTable1) + 'TXT'
我使用的是 sql server 2005。
任何帮助将不胜感激。
【问题讨论】:
真的不知道应该为 log_file 表做什么,因为它不在游标内,但我认为其余的会产生正确的结果 【参考方案1】:declare @countA int=0
begin tran
begin try
insert into TESTTable2(empNum, empName, eventDate,TestNum, Code, TestResult, Testprocess, ProcessName)
Select emp_no, emp_name, event_date, Test_no, Code, Test_result,userID+ 'TXT',userID
From test_table1
ORDER by emp_no
SET @CountA=@@ROWCOUNT
Insert into TESTTable3(testProcess, FileProcess, empNum)
Select userID+ 'TXT','EW' + userID,emp_no
From test_table1
Where code like 'D%'
ORDER by emp_no
commit tran
Insert into LOG_File(Name, Count, Processname) values ('Test1', @CountA,'@ProcessName')
end try
begin catch
rollback tran
SET @CountA =0
Insert into LOG_File(Name, Count, Processname) values ('Test1', @CountA,'@ProcessName')
SELECT ERROR_NUMBER() AS ErrorNumber,ERROR_MESSAGE() AS ErrorMessage
end catch
Select @CountA [TotalCount]
【讨论】:
上述代码的唯一问题是如果插入到 testTable2 失败,我不会收到错误消息。使用上面带有游标的存储过程,插入到 TestTable2 失败,然后我收到错误消息,告诉我插入失败的原因。现在,我只收到消息说(0 行受影响)。有什么办法,我尝试执行代码时会收到错误消息。以上是关于在sql存储过程中循环并删除游标的主要内容,如果未能解决你的问题,请参考以下文章
数据库基础详解:存储过程、视图、游标、SQL语句优化以及索引