SQL Proctest

Proctest

use pubs
go

if exists (SELECT * FROM sysobjects where name='c' and type='U')
	DROP TABLE c
go

if exists (SELECT * FROM sysobjects where name='b' and type='U')
	DROP TABLE b
go

if exists (SELECT * FROM sysobjects where name='a' and type='U')
	DROP TABLE a
go

if exists (SELECT * FROM sysobjects where name='test' and type='P')
	DROP PROC test
go

create table a (
 a char(1) primary key )

create table b (
 b char(1) references a)

create table c (
 c char(1))
go

create proc test as
begin transaction
insert c values ( 'X' )
Insert b values ( 'X' )   -- Fails reference
commit transaction
go

exec test
go

select *
 from c

-- Returns  `X'  !!

-- clear the row from c:
delete c 
go
-- Now here is a better formulation for the procedure:

drop proc test
go

create proc test as
begin transaction
insert c values ( 'X' )
	IF (@@error <> 0) GOTO on_error
Insert b values ( 'X' )   -- Fails reference
	IF (@@error <> 0) GOTO on_error	
commit transaction
return (0)

on_error:
rollback transaction
return (1)
go

declare @retcode int
exec @retcode=test
select @retcode

select *
 from c

-- clear the row from c:
delete c
go

-- Here is an alternative way to write the proc, to
-- abort if there is any error, without explictly 
-- checking for errors.
-- 
drop proc test
go

create proc test as
SET XACT_ABORT ON
begin transaction
insert c values ( 'X' )
Insert b values ( 'X' )   -- Fails reference
commit transaction
go

exec test
go

select *
 from c