I have a procedure that gets data from a table and inserts it into a temporary table. Then the procedure validates one by one in a while loop.
For example: I have 50 rows and the first row fails. In that case, I wish that the procedure continues processing the remaining 49 rows.
I'm forcing an error in an insert statement and and I put under it @@error <> 0
but does not enter if block.
But procedure ends and doesn't continues with the next statement to be executed.
I am running the procedure from Query Analyzer and put message with print 'line 1' etc etc.
Thank you for your help.
This is a similar example
create procedure procx
as
declare
@ind_max int,
@ind int,
@var_id int,
@var_name varchar(3)
declare @table_x table
(
row_id int identity(1,1),
id_x int,
name_x varchar(25),
status_x int
)
insert into @table_x values(1, 'xxx', 0)
insert into @table_x values(2, 'yyy', 0)
insert into @table_x values(3, 'zzz', 0)
set @ind_max = 3
set @ind = 1
while (@ind <= @ind_max)
begin
print 'line 1'
select @var_id = id_x ,
@var_name = name_x
from @table_x
where row_id = @ind
-- Forced error id_x is int field
-- Doesn't show line2, line3 ...
-- Msg 245, Level 16, State 1, Procedure procx, Line 160
-- Syntax error converting the varchar value 'A' to a column of data type int.
insert into test ( id_x , name_x )
values ( 'A' , @var_name )
if @@error != 0
begin
print 'line 2'
goto next_row
insert into log_test values(@var_id, 'Error')
end
print 'line 3'
update @table_x
set status_x = 1
where row_id = @ind
print 'line 4'
next_row:
set @ind = @ind + 1
end
print 'line 5'
Most likely you have a statement in between the error-causing statement and the IF
check. Simplifying the error handling logic here (since it is an extremely vast topic) and ignoring batch-aborting and connection-terminating errors...
This yields the error message and 'Uh oh'
:
SELECT 1/0;
PRINT 'Uh oh';
IF @@ERROR <> 0
BEGIN
PRINT 'Error.';
END
Since @@ERROR
gets reset after every statement, it is no longer non-zero, and the IF
block does not get entered. While the following works as expected, because we are checking @@ERROR
immediately after the trouble statement:
SELECT 1/0;
IF @@ERROR <> 0
BEGIN
PRINT 'Error.';
END
If you do have stuff you need to do in between, you can store the value in a variable:
DECLARE @err INT;
SELECT 1/0;
SELECT @err = @@ERROR;
PRINT 'Uh oh';
IF @err <> 0
BEGIN
PRINT 'Error.';
END
This will execute both PRINT
commands.
EDIT
Since you now added your code, I can give further insight into why this isn't working in your case. Invalid object is a severity 16 error:
Msg 208, Level 16, State 1, Procedure procx, Line 110
Invalid object name 'test'.
Now, according to the documentation , severity 16 does not abort the batch (only 19 and above), but that doesn't mean this is always true. For example, see this blog post which explains that in some cases sev16 can abort the batch. I don't have a 2000 instance anywhere around to test this for certain or to investigate workarounds, other than (a) not creating stored procedures that reference objects that don't exist or (b) upgrading to a modern version of SQL Server that has put a little more thought into error handling).
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.