在一个事务中更新架构和行,SQL Server 2005

在一个事务中更新架构和行,SQL Server 2005,sql,sql-server,sql-server-2005,transactions,ado,Sql,Sql Server,Sql Server 2005,Transactions,Ado,我目前正在更新一个遗留系统,它允许用户指定其中一个表的部分模式。用户可以通过此界面从表中创建和删除列。这个遗留系统使用ADO 2.8,并使用SQL Server 2005作为其数据库(您甚至不想知道在尝试使这个野兽现代化之前它使用的是什么数据库……但我离题了。) 在相同的编辑过程中,用户可以定义(并更改)可存储在这些用户创建字段中的有效值列表(如果用户希望限制字段中的值) 当用户更改字段的有效项列表时,如果删除了其中一个有效值,则允许用户选择一个新的“有效值”来映射其中包含此(现在无效)值的任何

我目前正在更新一个遗留系统,它允许用户指定其中一个表的部分模式。用户可以通过此界面从表中创建和删除列。这个遗留系统使用ADO 2.8,并使用SQL Server 2005作为其数据库(您甚至不想知道在尝试使这个野兽现代化之前它使用的是什么数据库……但我离题了。)

在相同的编辑过程中,用户可以定义(并更改)可存储在这些用户创建字段中的有效值列表(如果用户希望限制字段中的值)

当用户更改字段的有效项列表时,如果删除了其中一个有效值,则允许用户选择一个新的“有效值”来映射其中包含此(现在无效)值的任何行,以便它们现在再次具有有效值

在查看旧代码时,我注意到它极易将系统置于无效状态,因为上面提到的更改不是在事务中完成的(因此,如果其他人在上面提到的过程的中途进行了自己的更改…那么,您可以想象可能导致的问题)

问题是,我一直试图让它们在单个事务下更新,但每当代码到达更改该表架构的部分时,所有其他更改(更新行中的值,无论是在架构是否更改的表中…它们甚至可以是完全不相关的表)在事务中,直到该点为止的数据似乎都被悄悄地删除了。我没有收到指示它们已被删除的错误消息,并且当我在结束时提交事务时,不会引发任何错误。。。但是,当我查看应该在事务中更新的表时,只有新列在那里。未保存所做的任何非架构更改

到目前为止,在网上寻找答案被证明是浪费几个小时。。。所以我转向这里寻求帮助。有没有人尝试过通过ADO执行一个既更新表的模式又更新表中的行(无论是同一个表还是其他表)的事务?这是不允许的吗?在这种情况下,是否有任何文档可以提供帮助

编辑:

好的,我做了跟踪,这些命令被发送到数据库(括号中的解释)

(我不知道这里发生了什么,看起来它正在创建一个临时存储过程…?)

(检索保存用户生成字段定义信息的表)

(我想我的代码是在这里遍历它们的列表,获取当前信息)

(这似乎是我为定义输入修改数据的地方,我会逐一检查并更新自定义字段定义中发生的任何更改)

(这是我的代码在开始保存之前通过界面删除删除的内容的地方]…据我所知,这也是在该事务中实际发生的唯一事情)


ALTER TABLE CustomizableTable DROP COLUMN _weveknown;
(现在,如果对任何定义进行了更改,用户创建的列的属性需要更改,或者列上的索引需要添加/删除,那么就在这里完成,同时为尚未为给定列提供值的任何行提供默认值……请注意,据我所知,这一切实际上都没有发生当存储过程完成时。)


去
从sys.columns中选择*,其中object_id=object_id(N'customabletable')和name='\uu asdf'
去
ALTER TABLE可自定义ALTER列\uuuu asdf VarChar(50)NULL
去
如果存在(从sys.indexes中选择*,其中object_id=object_id(N'[dbo].[customabletable]')和name=N'idx_uuuuuuasdf')在可定制的(
__asdf ASC)带有(PAD_INDEX=OFF,SORT_IN_TEMPDB=OFF,DROP_EXISTING=OFF,IGNORE_DUP_KEY=OFF,ONLINE=OFF);
去
如果存在,则从中选择*(从sys.indexes中选择*,其中object\u id=object\u id(N'[dbo].[customabletable]')和name=N'idx\uuuuuuuuasdf')在上创建非聚集索引idx\uuuuuuuuasdf
可自定义(uuu asdf ASC),带有(PAD_INDEX=OFF,SORT_IN_TEMPDB=OFF,DROP_EXISTING=OFF,IGNORE_DUP_KEY=OFF,ONLINE=OFF);
去
更新可自定义集[\u asdf]='',其中[\u asdf]为空
去
从sys.columns中选择*,其中object_id=object_id(N'customabletable')和name='\u give'
去
ALTER TABLE可自定义ALTER列\u给定位NULL
去
如果存在(从sys.indexes中选择*,其中object_id=object_id(N'[dbo].[customabletable]',name=N'idx_uuuuugive')将索引idx_uugive放在可自定义的位置(ONLINE=OFF);
去
更新可自定义集[\u give]=0,其中[\u give]为空
去
从sys.columns中选择*,其中object_id=object_id(N'customabletable')和name='u up'
去
ALTER TABLE可自定义ALTER列\u up Int NULL
去
如果存在(从sys.indexes中选择*,其中object_id=object_id(N'[dbo].[customabletable]')和name=N'idx_____-up')将索引idx_-up放置在可定制上(联机=关闭);
去
更新可自定义设置[\u-up]=0,其中[\u-up]为空
去
从sys.columns中选择*,其中object_id=object_id(N'customabletable')和name='\u Testy'
去
ALTER TABLE可自定义ADD_Testy VarChar(50)NULL
去
如果存在(从sys.indexes中选择*,其中object_id=object_id(N'[dbo].[customabletable]')和name=N'idx___Testy')将索引idx_Testy放置在可自定义的上(在线=关闭);
去
更新可自定义集[\u Testy]='',其中[\u Testy]为空
去
从sys.columns中选择*,其中object_id=object_id(N'customabletable')和name='\u you'
去
ALTER TABLE可自定义ALTER列_youvarchar(250)NULL
去
如果存在(从sys.indexes中选择*,其中object_id=object_id(N'[dbo].[customabletab

exec sp_cursoropen @p1 output,N'SELECT * FROM CustomFieldDefs ORDER BY Sequence',@p3 output,@p4 output,@p5 output select @p1, @p3, @p4, @p5
go

exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursorfetch 180150003,1025,1,1
go
exec sp_cursorfetch 180150003,1028,1,1
go
exec sp_cursorfetch 180150003,32,1,1
go

exec sp_cursor 180150003,33,1,N'[CustomFieldDefs]',@Sequence=1,@Description='asdf',@Format='U|',@IsLookUp=1,@Length=50,@Properties='U|',@Required=1,@Title='__asdf',@Type='',@_Version=1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursor 180150003,33,1,N'[CustomFieldDefs]',@Sequence=2,@Description='give',@Format='Y',@IsLookUp=0,@Length=0,@Properties='',@Required=0,@Title='_give',@Type='B',@_Version=1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursor 180150003,33,1,N'[CustomFieldDefs]',@Sequence=3,@Description='up',@Format='###-##-####',@IsLookUp=0,@Length=0,@Properties='',@Required=0,@Title='_up',@Type='N',@_Version=1
go 
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursor 180150003,33,1,N'[CustomFieldDefs]',@Sequence=4,@Description='Testy',@Format='',@IsLookUp=0,@Length=50,@Properties='',@Required=0,@Title='_Testy',@Type='',@_Version=1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursor 180150003,33,1,N'[CustomFieldDefs]',@Sequence=5,@Description='you',@Format='U|',@IsLookUp=0,@Length=250,@Properties='U|',@Required=0,@Title='_you',@Type='',@_Version=1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursor 180150003,33,1,N'[CustomFieldDefs]',@Sequence=6,@Description='never',@Format='mm/dd/yyyy',@IsLookUp=0,@Length=0,@Properties='',@Required=0,@Title='_never',@Type='D',@_Version=1
go
exec sp_cursorfetch 180150003,32,1,1
go
exec sp_cursor 180150003,33,1,N'[CustomFieldDefs]',@Sequence=7,@Description='gonna',@Format='###-###-####',@IsLookUp=0,@Length=0,@Properties='',@Required=0,@Title='_gonna',@Type='C',@_Version=1
go
exec sp_cursorfetch 180150003,32,1,1
go

ALTER TABLE CustomizableTable DROP COLUMN _weveknown;
go SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'CustomizableTable') AND name = '__asdf' go ALTER TABLE CustomizableTable ALTER COLUMN __asdf VarChar(50) NULL go IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx___asdf') CREATE NONCLUSTERED INDEX idx___asdf ON CustomizableTable ( __asdf ASC) WITH (PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF); go select * from IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx___asdf') CREATE NONCLUSTERED INDEX idx___asdf ON CustomizableTable ( __asdf ASC) WITH (PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF); go UPDATE CustomizableTable SET [__asdf] = '' WHERE [__asdf] IS NULL go SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'CustomizableTable') AND name = '_give' go ALTER TABLE CustomizableTable ALTER COLUMN _give Bit NULL go IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx__give') DROP INDEX idx__give ON CustomizableTable WITH ( ONLINE = OFF ); go UPDATE CustomizableTable SET [_give] = 0 WHERE [_give] IS NULL go SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'CustomizableTable') AND name = '_up' go ALTER TABLE CustomizableTable ALTER COLUMN _up Int NULL go IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx__up') DROP INDEX idx__up ON CustomizableTable WITH ( ONLINE = OFF ); go UPDATE CustomizableTable SET [_up] = 0 WHERE [_up] IS NULL go SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'CustomizableTable') AND name = '_Testy' go ALTER TABLE CustomizableTable ADD _Testy VarChar(50) NULL go IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx__Testy') DROP INDEX idx__Testy ON CustomizableTable WITH ( ONLINE = OFF ); go UPDATE CustomizableTable SET [_Testy] = '' WHERE [_Testy] IS NULL go SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'CustomizableTable') AND name = '_you' go ALTER TABLE CustomizableTable ALTER COLUMN _you VarChar(250) NULL go IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx__you') DROP INDEX idx__you ON CustomizableTable WITH ( ONLINE = OFF ); go UPDATE CustomizableTable SET [_you] = '' WHERE [_you] IS NULL go SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'CustomizableTable') AND name = '_never' go ALTER TABLE CustomizableTable ALTER COLUMN _never DateTime NULL go IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx__never') DROP INDEX idx__never ON CustomizableTable WITH ( ONLINE = OFF ); go UPDATE CustomizableTable SET [_never] = '1/1/1900' WHERE [_never] IS NULL go SELECT * FROM sys.columns WHERE object_id = OBJECT_ID(N'CustomizableTable') AND name = '_gonna' go ALTER TABLE CustomizableTable ALTER COLUMN _gonna Money NULL go IF EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[dbo].[CustomizableTable]') AND name = N'idx__gonna') DROP INDEX idx__gonna ON CustomizableTable WITH ( ONLINE = OFF ); go UPDATE CustomizableTable SET [_gonna] = 0 WHERE [_gonna] IS NULL go exec sp_cursorclose 180150003 go