현재 사용자가 테이블 중 하나의 스키마 일부를 지시 할 수있는 레거시 시스템을 업데이트하고 있습니다. 사용자는이 인터페이스를 통해 테이블에서 열을 생성하고 제거 할 수 있습니다. 이 레거시 시스템은 ADO 2.8을 사용하고 있으며 데이터베이스로 SQL Server 2005를 사용하고 있습니다.이 짐승을 근대화하려는 시도가 시작되기 전에 어떤 데이터베이스를 사용했는지 알고 싶지는 않습니다 ...))SQL Server 2005의 단일 트랜잭션에서 스키마와 행 업데이트
동일한 편집 프로세스에서 사용자는 필드에있을 수있는 것을 제한하려는 경우 이러한 사용자 작성 필드에 저장할 수있는 유효한 값 목록을 정의하고 변경할 수 있습니다.
사용자가 필드의 유효한 항목 목록을 변경하면 유효한 값 중 하나를 제거하면이 "유효하지 않은"값이있는 행을 매핑하는 새로운 "유효한 값"을 선택할 수 있습니다. 이제 그들은 다시 유효한 값을 갖게됩니다.
이전 코드를 살펴보면, 위에서 언급 한 변경 사항이 트랜잭션 내에서 수행되지 않았기 때문에 시스템을 유효하지 않은 상태로 만드는 것이 매우 취약하다는 것을 알았습니다 (따라서 다른 누군가가 언급 된 프로세스의 중간에 오면 그들 자신의 변화를 만들었습니다 ... 음, 여러분은 발생할 수있는 문제들을 상상할 수 있습니다).
문제는, 나는 그것들을 단일 트랜잭션 하에서 업데이트하려고 노력했지만 코드가 그 테이블의 스키마를 변경하는 부분에 도착할 때마다 다른 모든 변경 사항 (행의 값 업데이트 , 스키마가 변경된 테이블에 있든 그렇지 않든 ... 완전히 관계없는 테이블 일 수도 있습니다.) 트랜잭션의 해당 시점까지 자동으로 삭제 된 것처럼 보입니다. 그들은 떨어 졌다는 것을 나타내는 오류 메시지가 나타나지 않으며 끝에 트랜잭션을 커밋 할 때 오류가 발생하지 않지만 트랜잭션에서 업데이트 될 예정인 테이블을 살펴볼 때 새 열만 거기 있어요. 스키마 이외의 변경 사항은 저장되지 않습니다.
답변에 대한 인터넷 검색은 지금까지 몇 시간의 낭비라고 판명되었으므로 여기 도움을 요청합니다. 누구도 테이블의 스키마를 업데이트하고 테이블의 행을 업데이트하는 ADO를 통해 트랜잭션을 수행하려고 시도 했습니까? (동일한 테이블 또는 다른 테이블 일 수 있습니까?) 허용되지 않습니까? 이 상황에서 도움이 될 수있는 문서가 있습니까?
편집 : 그것은을 만드는 것처럼
(나는 여기에서 무슨 일이 일어나고 있는지 모르는 보이는
좋아, 추적을했고,이 명령이 데이터베이스에 보내졌다 (괄호 안의 설명) 임시 저장 프로 시저 ...?)
declare @p1
int set @p1=180150003 declare @p3 int
set @p3=2 declare @p4 int set @p4=4
declare @p5 int set @p5=-1
(사용자가 생성 한 필드에 대한 정의 정보)를 보유하고있는 테이블을 불러 오는
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;
(있는 경우)이 트랜잭션 동안 발생 말할 수는 멀리 또한 유일한 일이 ... 인터페이스를 통해 삭제 제거하는 정의의 그 사용법이 r 생성 된 열의 속성을 변경하거나 열에 대한 색인을 추가/제거해야합니다. 여기에서 수행되며 지정된 열에 아직 값이없는 행에 기본값을 제공합니다. 저장 프로 시저가 끝날 때까지 내가 말할 수있는,이 중 어느 것도 실제로 발생하지 점에 유의.)
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
그 후 o 위의 경우 열의 삭제 만 발생합니다. 트랜잭션 전후의 모든 내용이 무시 된 것처럼 보이며 SQL Trace에 트랜잭션 중에 문제가 있음을 알리는 메시지가 없습니다.
예, 트랜잭션에서 트랜잭션을 수행하기 위해 클라이언트 측 커서를 사용할 수 없다는 것을 설명서에서 읽었습니다. 또한 클라이언트 측 커서를 사용할 수 없었습니다. 모두 같은 활성 연결을 사용합니다. 도움을 주셔서 감사합니다. 확실히 이상한 문제였습니다. ( – EdgarVerona
스토어드 프로 시저에 대한 좋은 정보도 있습니다. 그런 느낌이었습니다. , 그러나 나는 확실하지 않았다 ... 나는 실제로 오늘 전에 Trace를 한 적이 없었으므로, 그런 종류의 절차가 후드 아래에서 호출되는 것을 결코 보지 못했다. =) =) – EdgarVerona
걱정하지 말고, 당신은 최선을 다했다. 주어진 정보와 함께 할 수 있습니다. 나는 그것에 대한 나의 머리를 잘 긁어 모으고있다. .. 예, 나는 당신이 말한 것처럼 Recordset.Update를 실제 행 업데이트에 대해 지금 사용하고있다 ... 나는 직접 생성 된 Update 문을 대신 사용해보고 어떻게 작동하는지 보게 될 것이다. . – EdgarVerona