如何为SQL中的每个SQL执行语句设置转到错误处理程序并回滚? [英] How to set go to error handler and roll back for each SQL execution statements in SQL?

查看:60
本文介绍了如何为SQL中的每个SQL执行语句设置转到错误处理程序并回滚?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

How to set go to error handler and roll back  for each sql execution statements in Sql?


<pre lang="SQL">/****** Object:  StoredProcedure [dbo].[Remove_Identity_Columns]    Script Date: 04/11/2016 18:32:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


--exec CHK_INST_IDENTFIER &#39;400220101&#39;,&#39;&#39;,&#39;&#39;  
--exec Remove_Identity_Columns 
ALTER proc [dbo].[Remove_Identity_Columns]

as
--Create a Temporary Table @Identity_Details to which Identity Value,Schema Name,Table/Column Name/Data Type from Identity Insert Tables Data is Passed

declare @Identity_Details table
(
	IDVal int identity(1,1) ,
	SchemaName varchar(25),
	TableName varchar(25),
	ColumnName varchar(25),
	DataType varchar(10)

)

declare @Foreign_keys table
(
	Idval int identity(1,1),
	ForeignKeyName varchar(1000),
	ParentTable varchar(100)

)

declare 
	@NewColumn_Creation_Query nvarchar(1000),
	@UpdateColumn_Query nvarchar(1000),
	@Column_Rename_Query nvarchar(1000),
	@Primary_Key_Creation_Query nvarchar(1000),
	@DropColumn_Query nvarchar(1000),
	@Leadingstring varchar(5),
	@SchemaName varchar(25),
	@TableName varchar(25),
	@ColumnName varchar(25),
	@DataType varchar(10),
	@Count int,
	@Loop int,
	@Count_FK int,
	@Loop_FK int,
	@Drop_Key_Query nvarchar(1000)

BEGIN TRAN

insert @Identity_Details
(
	SchemaName,
	TableName,
	ColumnName,
	DataType
)
    -- Schema/Table Name/Column Name/Data Type etc with Identity Insert Columns passed  to Temporary Table @Identity_Details 
	select                        
	c.TABLE_SCHEMA ,
	t.TABLE_NAME ,
	c.COLUMN_NAME,        
	c.DATA_TYPE  
	from                       
	information_schema.columns c
	inner join    
	information_schema.tables    t             
	on t.TABLE_NAME = c.TABLE_NAME
	where
	columnproperty(object_id(c.TABLE_NAME),c.COLUMN_NAME, &#39;IsIdentity&#39;) = 1 
	--End

   -- Column Names with _dup suffixed and count etc passed to Temporary Table @Identity_Details
	select 
	@Leadingstring= &#39;_dup&#39;,
	@Count        =count(*),
	@Loop		  = 1,
	@NewColumn_Creation_Query = &#39;&#39;,
	@UpdateColumn_Query=&#39;&#39;,
	@DropColumn_Query=&#39;&#39;,
	@Column_Rename_Query=&#39;&#39;,
	@Primary_Key_Creation_Query=&#39;&#39;
	from
	@Identity_Details
    --End

--Passing the Identity Insert Tables one by one from Temporary Table with Table/Column/Schema Names of the same one by one in the While Loop
while(@Loop&lt;=@Count)
begin
	select
		@SchemaName = SchemaName,
		@TableName  = TableName,
		@ColumnName  = ColumnName,
		@DataType    = DataType
	from @Identity_Details
	where IDVal = @Loop
	
    --To each identity insert a new column created with _dup suffixed(Leading String)
	select @NewColumn_Creation_Query = &#39;ALTER TABLE &#39; + @SchemaName + &#39;.&#39;+ @TableName + &#39; ADD &#39; +@ColumnName  + @Leadingstring + &#39; &#39; +  @DataType 

	exec sp_executesql @NewColumn_Creation_Query

	 Print &#39;New Column Creation Completed Successfully&#39;
	 --End
     --To each identity update data in the Temp Column newly created (_dup) to Real Column
	select @UpdateColumn_Query = &#39;UPDATE &#39; + @SchemaName + &#39;.&#39;+@TableName + &#39; SET &#39; + @ColumnName +  @Leadingstring+ &#39; = &#39; + @ColumnName 

	exec sp_executesql 	@UpdateColumn_Query
  
	Print &#39;New Column Values Updated with Existing Values&#39;
	--End 

	---exec Drop_FK @TableName
	
	--Drop the Foreign key Constriants of Newly Created Tables
	insert @Foreign_keys (ForeignKeyName,ParentTable)
	select name,object_name([parent_object_id])
	from sys.foreign_keys  
	where object_name([referenced_object_id]) = @TableName
	
	
	
	select
		@Count_FK  = max(IDVal),
		@Loop_FK   = MIN(IdVal) 
	from
		@Foreign_keys	
	
	while(@Loop_FK&lt;=@Count_FK)
	begin
		select @Drop_Key_Query =  &#39;ALTER TABLE &#39; + ParentTable + &#39; DROP CONSTRAINT &#39; + ForeignKeyName
		from @Foreign_keys where Idval = @Loop_FK
        --select  @Drop_Key_Query
		exec sp_executesql 	@Drop_Key_Query
		select @Drop_Key_Query = &#39;&#39;
		select @Loop_FK =  @Loop_FK + 1

	end
	
   
	Print &#39;All the Foreign key Constriants Dropped&#39;
   --End

	---exec DropAllColumnConstraints  @TableName,@ColumnName
	--Drop All Column Constraints
	while 0=0 begin
      declare @constraintName varchar(128)
      set @constraintName = (
         select top 1 constraint_name
            from information_schema.constraint_column_usage
            where table_name = @tableName and column_name = @columnName )
      if @constraintName is null break
      --print (&#39;alter table &quot;&#39;+@tableName+&#39;&quot; drop constraint &quot;&#39;+@constraintName+&#39;&quot;&#39;)
      exec (&#39;alter table &quot;&#39;+@TableName+&#39;&quot; drop constraint &quot;&#39;+@constraintName+&#39;&quot;&#39;)
    end
	Print &#39;Primary key Constriants Dropped&#39;
	--End
	
     --Already Existing Columns dropped afterwards. 
	select @DropColumn_Query = &#39;ALTER TABLE &#39;+ @SchemaName + &#39;.&#39;+@TableName + &#39; DROP COLUMN &#39; + @ColumnName
	--PRINT @DropColumn_Query
	exec sp_executesql 	@DropColumn_Query 
	Print &#39;Already Exisiting Columns Dropped&#39;
	--End

    --Rename Columns with_dup suffixed to Column already existed before   
	select @Column_Rename_Query =  &#39;exec sp_rename &#39; + &#39;&#39;&#39;&#39; + @SchemaName + &#39;.&#39; + @TableName + &#39;.&#39; +@ColumnName + @Leadingstring +&#39;&#39;&#39;&#39; + &#39;,&#39;  + &#39;&#39;&#39;&#39; + @ColumnName + &#39;&#39;&#39;&#39; + &#39;,&#39; + &#39;&#39;&#39;&#39; +&#39;COLUMN&#39; +&#39;&#39;&#39;&#39;
	-- Print @Column_Rename_Query
	exec sp_executesql 	@Column_Rename_Query 
	Print &#39;Column Name Renamed from Temporary to Original Existing Column Names&#39;
	--End

    --Set the New Column renamed as not null    
	select @NewColumn_Creation_Query = &#39;ALTER TABLE &#39; + @SchemaName + &#39;.&#39;+ @TableName + &#39; ALTER COLUMN &#39; +@ColumnName  + &#39; &#39; + @DataType  + &#39; Not Null&#39;
	--PRINT  @NewColumn_Creation_Query
	exec sp_executesql 	@NewColumn_Creation_Query
	Print &#39;New Column Name Data Type set as Not Nullable&#39;
    --End
    
    --Primary Key Constraint Added  for Identity Insert Columns
	select @Primary_Key_Creation_Query = &#39;ALTER TABLE &#39; +  @SchemaName + &#39;.&#39; + @TableName  + &#39; add constraint &#39; + &#39;PK_&#39; + @TableName + +&#39;_&#39; + @ColumnName+&#39; primary key(&#39; + &#39;[&#39;+@ColumnName+&#39;]&#39; + &#39;)&#39;
	--Print @Primary_Key_Creation_Query
	exec sp_executesql 	@Primary_Key_Creation_Query 
	Print &#39;Primary Key Constraint Added for Primary Key Columns&#39;
	--End	
	
	select 
		@Loop = @Loop + 1,
		@NewColumn_Creation_Query = &#39;&#39;,
		@UpdateColumn_Query = &#39;&#39;,
		@Column_Rename_Query = &#39;&#39;,
		@Primary_Key_Creation_Query = &#39;&#39;,
		@DropColumn_Query = &#39;&#39;
		
		delete from @Foreign_keys


end
COMMIT TRAN</pre>





我的尝试:



脚本我正在使用:



/ ******对象:StoredProcedure [dbo]。[Remove_Identity_Columns]脚本日期:04/11 / 2016 18:32:54 ****** /

SET ANSI_NULLS ON

GO

SET QUOTED_IDENTIFIER ON

GO





--exec CHK_INST_IDENTFIER'400220101','',''

- -exec Remove_Identity_Columns

ALTER proc [dbo]。[Remove_Identity_Columns]



as

- 创建一个临时的表@Identity_Details通过标识插入表数据传递的标识值,模式名称,表/列名称/数据类型



声明@Id entity_Details表



IDVal int identity(1,1),

SchemaName varchar(25),

TableName varchar(25),

ColumnName varchar(25),

DataType varchar(10)







声明@Foreign_keys表



Idval int identity(1,1),

ForeignKeyName varchar(1000),

ParentTable varchar(100)







声明

@NewColumn_Creation_Query nvarchar(1000),

@UpdateColumn_Query nvarchar(1000),

@Column_Rename_Query nvarchar(1000 ),

@Primary_Key_Creation_Query nvarchar(1000),

@DropColumn_Query nvarchar(1000),

@Leadingstring varchar(5),
@SchemaName varchar(25),

@TableName varchar(25),

@ColumnName varchar(25),

@DataType varchar(10),

@Count int,

@Loop int,

@Count_FK int,

@Lo op_FK int,

@Drop_Key_Query nvarchar(1000)



BEGIN TRAN



插入@Identity_Details



SchemaName,

TableName,

ColumnName,

DataType



- 模式/表名/列名/数据类型等,标识插入列传递给临时表@Identity_Details

选择

c.TABLE_SCHEMA,

t.TABLE_NAME,

c.COLUMN_NAME,

c.DATA_TYPE

来自

information_schema.columns c

内部联接

information_schema.tables t

on t.TABLE_NAME = c.TABLE_NAME

其中

columnproperty(object_id(c.TABLE_NAME),c.COLUMN_NAME,'IsIdentity')= 1

- 结束



- 带有_dup后缀和计数等的列名传递给临时表@Identity_Detail s $

选择

@ Leadingstring ='_ dup',

@Count = count(*),

@循环= 1,

@NewColumn_Creation_Query ='',

@ UpdateColumn_Query ='',

@ DropColumn_Query ='',

@ Column_Rename_Query ='',

@ Primary_Key_Creation_Query =''

来自

@Identity_Details

--End



- 在临时表中逐个传递标识表,同时在While循环中逐一列出表/列/模式名称br />
while(@ Loop< = @ Count)

begin

select

@SchemaName = SchemaName,
@TableName = TableName,

@ColumnName = ColumnName,

@DataType = DataType
来自@Identity_Details的


其中IDVal = @Loop



- 每个身份插入一个用_dup后缀创建的新列(前导字符串)

选择@NewColu mn_Creation_Query ='ALTER TABLE'+ @SchemaName +'。'+ @TableName +'ADD'+ @ ColumnName + @Leadingstring +''+ @DataType



exec sp_executesql @NewColumn_Creation_Query



打印'新列创建成功完成'

- 结束

- 每个身份将新创建的临时列中的数据(_dup)更新为实列

选择@UpdateColumn_Query ='UPDATE'+ @SchemaName +'。'+@TableName +'SET'+ @ColumnName + @ Leadingstring +' ='+ @ColumnName



exec sp_executesql @UpdateColumn_Query



打印'使用现有值更新的新列值'

- 结束



--- exec Drop_FK @TableName



- 删除新创建的表的外键构词

insert @Foreign_keys(ForeignKeyName,ParentTable)

select name,object_name([parent_object_id])

其中object_name([referenced_object_id])= @TableName





$ / b
选择

@Count_FK = max(IDVal),

@Loop_FK = MIN(IdVal)

来自

@Foreign_keys



while(@ Loop_FK< = @ Count_FK)

开始

选择@Drop_Key_Query ='ALTER TABLE'+ ParentTable +'DROP CONSTRAINT'+ ForeignKeyName
来自@Foreign_keys的
其中Idval = @Loop_FK

- 选择@Drop_Key_Query

exec sp_executesql @Drop_Key_Query

select @Drop_Key_Query =''

select @Loop_FK = @Loop_FK + 1



结束





打印'所有外国钥匙造物商掉落'

- -End



--- exec DropAllColumnConstraints @ TableName,@ ColumnName

--Drop All Column Constraints

而0 = 0开始

声明@constraintName varchar(128)

set @constraintName =(

从info_schema.constraint_column_usage中选择top 1 constraint_name



其中table_name = @tableName和column_name = @columnName)

如果@constraintName为null break

--print('alter table' + @ tableName +'drop constraint'+ @ constraintName +'')

exec('alter table'+ @ TableName +'drop constraint'+ @ constraintName +'')

结束

打印'主要关键字Constriants掉落'

- 结束



- 已经存在的列已经丢失了。

选择@DropColumn_Query ='ALTER TABLE'+ @SchemaName +'。'+ @ TableName +'DROP COLUMN'+ @ColumnName

--PRINT @DropColumn_Query

exec sp_executesql @DropColumn_Query

打印'已经存在的列已经丢失'

- 结束



- 在列之前已经存在列的with_dup列的列号已经存在

选择@Column_Rename_Query ='exec sp_rename'+''''+ @SchemaName +'。'+ @TableName +'。'+ @ ColumnName + @Leadingstring +''''+','+''''+ @ColumnName +''''+','+''''+'COLUMN'+''''

- 打印@Column_Rename_Query

exec sp_executesql @Column_Rename_Query

打印'列名从临时名称重命名为原始列名'

- 结束



- 将New Column重命名为not null

select @NewColumn_Creation_Query =' ALTER TABLE'+ @SchemaName +'。'+ @TableName +'ALTER COLUMN'+ @ ColumnName +''+ @DataType +'Not Null'

--PRINT @NewColumn_Creation_Query

exec sp_executesql @NewColumn_Creation_Query

打印'新列名数据类型设置为不可为空'

- 结束



- 为标识插入列添加主键约束

选择@Primary_Key_Creation_Query ='ALTER TABLE'+ @SchemaName +'。'+ @TableName +'添加约束'+'PK_'+ @TableName + +'_'+ @ ColumnName +'主键('+'['+ @ ColumnName +']'+')'

- 打印@Primary_Key_Creation_Query

exec sp_executesql @Primary_Key_Creation_Query

打印'为主键列添加的主键约束'

- 结束



选择

@Loop = @Loop + 1,

@NewColumn_Creation_Query ='',

@UpdateCo lumn_Query ='',

@Column_Rename_Query ='',

@Primary_Key_Creation_Query ='',

@DropColumn_Query =''



从@Foreign_keys删除





结束

COMMIT TRAN



What I have tried:

Script I am using:

/****** Object: StoredProcedure [dbo].[Remove_Identity_Columns] Script Date: 04/11/2016 18:32:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


--exec CHK_INST_IDENTFIER '400220101','',''
--exec Remove_Identity_Columns
ALTER proc [dbo].[Remove_Identity_Columns]

as
--Create a Temporary Table @Identity_Details to which Identity Value,Schema Name,Table/Column Name/Data Type from Identity Insert Tables Data is Passed

declare @Identity_Details table
(
IDVal int identity(1,1) ,
SchemaName varchar(25),
TableName varchar(25),
ColumnName varchar(25),
DataType varchar(10)

)

declare @Foreign_keys table
(
Idval int identity(1,1),
ForeignKeyName varchar(1000),
ParentTable varchar(100)

)

declare
@NewColumn_Creation_Query nvarchar(1000),
@UpdateColumn_Query nvarchar(1000),
@Column_Rename_Query nvarchar(1000),
@Primary_Key_Creation_Query nvarchar(1000),
@DropColumn_Query nvarchar(1000),
@Leadingstring varchar(5),
@SchemaName varchar(25),
@TableName varchar(25),
@ColumnName varchar(25),
@DataType varchar(10),
@Count int,
@Loop int,
@Count_FK int,
@Loop_FK int,
@Drop_Key_Query nvarchar(1000)

BEGIN TRAN

insert @Identity_Details
(
SchemaName,
TableName,
ColumnName,
DataType
)
-- Schema/Table Name/Column Name/Data Type etc with Identity Insert Columns passed to Temporary Table @Identity_Details
select
c.TABLE_SCHEMA ,
t.TABLE_NAME ,
c.COLUMN_NAME,
c.DATA_TYPE
from
information_schema.columns c
inner join
information_schema.tables t
on t.TABLE_NAME = c.TABLE_NAME
where
columnproperty(object_id(c.TABLE_NAME),c.COLUMN_NAME, 'IsIdentity') = 1
--End

-- Column Names with _dup suffixed and count etc passed to Temporary Table @Identity_Details
select
@Leadingstring= '_dup',
@Count =count(*),
@Loop = 1,
@NewColumn_Creation_Query = '',
@UpdateColumn_Query='',
@DropColumn_Query='',
@Column_Rename_Query='',
@Primary_Key_Creation_Query=''
from
@Identity_Details
--End

--Passing the Identity Insert Tables one by one from Temporary Table with Table/Column/Schema Names of the same one by one in the While Loop
while(@Loop<=@Count)
begin
select
@SchemaName = SchemaName,
@TableName = TableName,
@ColumnName = ColumnName,
@DataType = DataType
from @Identity_Details
where IDVal = @Loop

--To each identity insert a new column created with _dup suffixed(Leading String)
select @NewColumn_Creation_Query = 'ALTER TABLE ' + @SchemaName + '.'+ @TableName + ' ADD ' +@ColumnName + @Leadingstring + ' ' + @DataType

exec sp_executesql @NewColumn_Creation_Query

Print 'New Column Creation Completed Successfully'
--End
--To each identity update data in the Temp Column newly created (_dup) to Real Column
select @UpdateColumn_Query = 'UPDATE ' + @SchemaName + '.'+@TableName + ' SET ' + @ColumnName + @Leadingstring+ ' = ' + @ColumnName

exec sp_executesql @UpdateColumn_Query

Print 'New Column Values Updated with Existing Values'
--End

---exec Drop_FK @TableName

--Drop the Foreign key Constriants of Newly Created Tables
insert @Foreign_keys (ForeignKeyName,ParentTable)
select name,object_name([parent_object_id])
from sys.foreign_keys
where object_name([referenced_object_id]) = @TableName



select
@Count_FK = max(IDVal),
@Loop_FK = MIN(IdVal)
from
@Foreign_keys

while(@Loop_FK<=@Count_FK)
begin
select @Drop_Key_Query = 'ALTER TABLE ' + ParentTable + ' DROP CONSTRAINT ' + ForeignKeyName
from @Foreign_keys where Idval = @Loop_FK
--select @Drop_Key_Query
exec sp_executesql @Drop_Key_Query
select @Drop_Key_Query = ''
select @Loop_FK = @Loop_FK + 1

end


Print 'All the Foreign key Constriants Dropped'
--End

---exec DropAllColumnConstraints @TableName,@ColumnName
--Drop All Column Constraints
while 0=0 begin
declare @constraintName varchar(128)
set @constraintName = (
select top 1 constraint_name
from information_schema.constraint_column_usage
where table_name = @tableName and column_name = @columnName )
if @constraintName is null break
--print ('alter table "'+@tableName+'" drop constraint "'+@constraintName+'"')
exec ('alter table "'+@TableName+'" drop constraint "'+@constraintName+'"')
end
Print 'Primary key Constriants Dropped'
--End

--Already Existing Columns dropped afterwards.
select @DropColumn_Query = 'ALTER TABLE '+ @SchemaName + '.'+@TableName + ' DROP COLUMN ' + @ColumnName
--PRINT @DropColumn_Query
exec sp_executesql @DropColumn_Query
Print 'Already Exisiting Columns Dropped'
--End

--Rename Columns with_dup suffixed to Column already existed before
select @Column_Rename_Query = 'exec sp_rename ' + '''' + @SchemaName + '.' + @TableName + '.' +@ColumnName + @Leadingstring +'''' + ',' + '''' + @ColumnName + '''' + ',' + '''' +'COLUMN' +''''
-- Print @Column_Rename_Query
exec sp_executesql @Column_Rename_Query
Print 'Column Name Renamed from Temporary to Original Existing Column Names'
--End

--Set the New Column renamed as not null
select @NewColumn_Creation_Query = 'ALTER TABLE ' + @SchemaName + '.'+ @TableName + ' ALTER COLUMN ' +@ColumnName + ' ' + @DataType + ' Not Null'
--PRINT @NewColumn_Creation_Query
exec sp_executesql @NewColumn_Creation_Query
Print 'New Column Name Data Type set as Not Nullable'
--End

--Primary Key Constraint Added for Identity Insert Columns
select @Primary_Key_Creation_Query = 'ALTER TABLE ' + @SchemaName + '.' + @TableName + ' add constraint ' + 'PK_' + @TableName + +'_' + @ColumnName+' primary key(' + '['+@ColumnName+']' + ')'
--Print @Primary_Key_Creation_Query
exec sp_executesql @Primary_Key_Creation_Query
Print 'Primary Key Constraint Added for Primary Key Columns'
--End

select
@Loop = @Loop + 1,
@NewColumn_Creation_Query = '',
@UpdateColumn_Query = '',
@Column_Rename_Query = '',
@Primary_Key_Creation_Query = '',
@DropColumn_Query = ''

delete from @Foreign_keys


end
COMMIT TRAN

推荐答案

对于我所知道的开始交易,如果您更深入地使用它,对于您想要的每个流程,您可以按顺序为每个交易分配一个标识符知道崩溃和回滚到你想要的交易的位置。



看看这里 BEGIN TRANSACTION(Transact-SQL) [ ^ ]



此处为回滚事务ROLLBACK TRANSACTION(Transact-SQL) [ ^ ]



希望这有助于
For what i know about "Begin transaction" if you use it more deeply, for each process you want, you can assign an identifier to each transaction in order to know where it crashes and rollback to the transaction you want.

Take a look here BEGIN TRANSACTION (Transact-SQL)[^]

And here for the rollback transactions ROLLBACK TRANSACTION (Transact-SQL)[^]

Hope this helps


这篇关于如何为SQL中的每个SQL执行语句设置转到错误处理程序并回滚?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆