IT

"테이블을 다시 만들어야 하는 변경 내용 저장 방지" 부정적 영향

itgroup 2023. 4. 28. 20:29
반응형

"테이블을 다시 만들어야 하는 변경 내용 저장 방지" 부정적 영향

서문

오늘 SQL Server 2008에서 데이터 유형을 통화(18,0)에서 (19,2)로 변경하여 열을 수정했습니다.

SQL Server에서 "변경한 내용을 삭제하고 다시 만들어야 합니다." 오류가 발생했습니다.

답변을 드리기 전에 다음을 읽어 주십시오.

도구 ► 옵션 디자이너 테이블데이터베이스 디자이너 ► "테이블 재작성이 필요한 변경사항 저장 금지" 상자의 선택을 취소하므로...이 옵션으로 응답하지 마십시오!

실제 문제

제 실제 질문은 다음과 같이 다른 것에 대한 것입니다.

이 작업의 부정적인 영향/가능한 단점이 있습니까?

이 상자를 선택하지 않으면 테이블이 자동으로 삭제되고 다시 생성됩니까?

그렇다면 테이블 복사본은 원본 테이블의 100% 정확한 복제본입니까?

도구 --> 선택사항 --> 설계자 노드 --> "테이블 재생성이 필요한 변경사항 저장 금지" 선택을 취소합니다.

테이블은 SQL Server의 Management Studio가 테이블을 삭제하고 다시 생성하는 유일한 방법으로 프로그래밍된 경우에만 삭제되고 다시 생성됩니다.

그럴 필요가 없을 때 그럴 수도 있지만, Management Studio에서 편집한 내용이 삭제되지 않고 다시 생성될 필요가 없기 때문에 삭제할 수도 있습니다.

문제는 모든 사례를 열거하고 어느 쪽에 해당하는지 판단하는 것이 상당히 지루할 것이라는 점입니다.

이것이 제가 하는 일을 숨기는 시각적 디자이너(그리고 솔직히 버그가 있음) 대신 쿼리 창에서 사용하는 것을 좋아하는 이유입니다. 저는 정확히 무슨 일이 일어날지 알고 있으며, 유일한 가능성이 테이블을 떨어뜨리고 다시 만드는 것뿐인 경우에 대비할 수 있습니다(SSMS가 사용자에게 수행하는 빈도보다 약간 적은 횟수).

이 작업의 부정적인 영향/가능한 단점이 있습니까?

물론입니다. 전체 테이블을 재구성하지 않고 직접 변경 내용을 스크립팅할 수 있다면, 테이블이 10TB이고 데이터베이스가 많이 로그에 기록되어 있고(동기화 AG, 변경 추적, 복제, 잘못 작성된 트리거 등) 테이블 액세스가 높은 경우를 생각해 보십시오. 이는 잠재적인 재해의 원인이 됩니다.GUI가 모두 또는 아무것도 하지 않고 온라인 힌트를 적용하거나 열을 추가하고 데이터를 일괄적으로 복사할 수 있는 변경 사항이라면 이 방법이 더 좋습니다.

이 상자를 선택하지 않으면 테이블이 자동으로 삭제되고 다시 생성됩니까?

그럴 수도 있어요.시나리오 목록이 있으며 결과는 SSMS 버전, SQL Server 버전, 때로는 버전에 따라 달라집니다.확인란을 선택하고 데이터베이스의 의미 없는 복사본에 변경사항을 먼저 적용하려고 하면 확인할 수 있지만, 포인트 클릭 GUI 대신 실제 ALTER TABLE 스크립트를 사용하는 것이 IMHO로 가는 방법입니다.

그렇다면 테이블 복사본은 원본 테이블의 100% 정확한 복제본입니까?

예, SSMS가 테이블을 다시 작성해야 하는 경우, 작업이 완료된 후(코스 변경 제외) 100% 정확한 복제본이 되지만, 다음 주 수요일이 될 수 있습니다.이 프로세스는 테이블의 새 버전을 만들고 모든 데이터를 테이블에 복사한 다음 이전 테이블을 삭제하고 새 테이블의 이름을 바꿉니다.

참조 - 이 옵션을 해제하면 테이블을 다시 만들지 않고 변경사항이 손실될 수도 있습니다.예를 들어 SQL Server 2008에서 변경 추적 기능을 실행하여 테이블의 변경 내용을 추적한다고 가정합니다.테이블을 다시 만드는 작업을 수행하면 "증상" 섹션에 언급된 오류 메시지가 표시됩니다.그러나 이 옵션을 해제하면 테이블이 다시 생성될 때 기존 변경 추적 정보가 삭제됩니다.따라서 옵션을 해제하여 이 문제를 해결하지 않는 것이 좋습니다.

SQL Server는 다음과 같은 경우에만 테이블을 삭제하고 다시 만듭니다.

  • 새 열 추가
  • 열의 Null 허용 설정 변경
  • 표의 열 순서 변경
  • 열 데이터 유형 변경

테이블을 다시 만드는 동안 메타데이터가 손실될 경우 데이터가 손실되므로 ALTER를 사용하는 것이 더 안전합니다.

예, 다음과 같은 부정적인 영향이 있습니다.

이 플래그에 의해 차단된 변경 사항을 스크립트로 작성하면 아래와 같은 스크립트가 표시됩니다(연락처의 ID 열을 자동 번호 IDITY 열로 전환하지만 테이블에는 종속성이 있습니다).다음을 실행하는 동안 발생할 수 있는 잠재적 오류를 기록합니다.

  1. 심지어 마이크로소프트도 이것이 데이터 손실을 야기할 수 있다고 경고합니다(댓글은 자동으로 생성됩니다)!
  2. 일정 기간 동안 외부 키가 적용되지 않습니다.
  3. 이 ssms 단위로 수동으로 실행하면 'EXEC('INSERT INTO')가 실패하고 다음 문이 실행되도록 허용하면('go'로 분할되어 기본적으로 실행됨) 0개의 행을 삽입한 다음 이전 테이블을 삭제합니다.
  4. 이것이 큰 테이블인 경우, 삽입의 런타임이 클 수 있고 트랜잭션이 스키마 수정 잠금을 보유하고 있으므로 많은 것을 차단합니다.

--

/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/

BEGIN TRANSACTION
GO
ALTER TABLE raw.Contact
    DROP CONSTRAINT fk_Contact_AddressType
GO
ALTER TABLE ref.ContactpointType SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.Contact
    DROP CONSTRAINT fk_contact_profile
GO
ALTER TABLE raw.Profile SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
CREATE TABLE raw.Tmp_Contact
    (
    ContactID int NOT NULL IDENTITY (1, 1),
    ProfileID int NOT NULL,
    AddressType char(2) NOT NULL,
    ContactText varchar(250) NULL
    )  ON [PRIMARY]
GO
ALTER TABLE raw.Tmp_Contact SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT raw.Tmp_Contact ON
GO
IF EXISTS(SELECT * FROM raw.Contact)
     EXEC('INSERT INTO raw.Tmp_Contact (ContactID, ProfileID, AddressType, ContactText)
        SELECT ContactID, ProfileID, AddressType, ContactText FROM raw.Contact WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT raw.Tmp_Contact OFF
GO
ALTER TABLE raw.PostalAddress
    DROP CONSTRAINT fk_AddressProfile
GO
ALTER TABLE raw.MarketingFlag
    DROP CONSTRAINT fk_marketingflag_contact
GO
ALTER TABLE raw.Phones
    DROP CONSTRAINT fk_phones_contact
GO
DROP TABLE raw.Contact
GO
EXECUTE sp_rename N'raw.Tmp_Contact', N'Contact', 'OBJECT' 
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
    Idx_Contact_1 PRIMARY KEY CLUSTERED 
    (
    ProfileID,
    ContactID
    ) 

GO
ALTER TABLE raw.Contact ADD CONSTRAINT
    Idx_Contact UNIQUE NONCLUSTERED 
    (
    ProfileID,
    ContactID
    ) 

GO
CREATE NONCLUSTERED INDEX idx_Contact_0 ON raw.Contact
    (
    AddressType
    ) 
GO
ALTER TABLE raw.Contact ADD CONSTRAINT
    fk_contact_profile FOREIGN KEY
    (
    ProfileID
    ) REFERENCES raw.Profile
    (
    ProfileID
    ) ON UPDATE  NO ACTION 
     ON DELETE  NO ACTION 

GO
ALTER TABLE raw.Contact ADD CONSTRAINT
    fk_Contact_AddressType FOREIGN KEY
    (
    AddressType
    ) REFERENCES ref.ContactpointType
    (
    ContactPointTypeCode
    ) ON UPDATE  NO ACTION 
     ON DELETE  NO ACTION 

GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.Phones ADD CONSTRAINT
    fk_phones_contact FOREIGN KEY
    (
    ProfileID,
    PhoneID
    ) REFERENCES raw.Contact
    (
    ProfileID,
    ContactID
    ) ON UPDATE  NO ACTION 
     ON DELETE  NO ACTION 

GO
ALTER TABLE raw.Phones SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.MarketingFlag ADD CONSTRAINT
    fk_marketingflag_contact FOREIGN KEY
    (
    ProfileID,
    ContactID
    ) REFERENCES raw.Contact
    (
    ProfileID,
    ContactID
    ) ON UPDATE  NO ACTION 
     ON DELETE  NO ACTION 

GO
ALTER TABLE raw.MarketingFlag SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE raw.PostalAddress ADD CONSTRAINT
    fk_AddressProfile FOREIGN KEY
    (
    ProfileID,
    AddressID
    ) REFERENCES raw.Contact
    (
    ProfileID,
    ContactID
    ) ON UPDATE  NO ACTION 
     ON DELETE  NO ACTION 

GO
ALTER TABLE raw.PostalAddress SET (LOCK_ESCALATION = TABLE)
GO
COMMIT

언급URL : https://stackoverflow.com/questions/11802429/prevent-saving-changes-that-require-the-table-to-be-re-created-negative-effect

반응형