무엇을하기 전에 @RDFozz가 제기 한 질문을 질문에 대한 의견에서 고려하십시오.
있습니까 어떤 외에 다른 소스 [Q].[G]
이 테이블을 채우기는?
응답이 " 이 대상 테이블 의 유일한 데이터 원본 임을 100 % 확신합니다"이외의 항목 인 경우 , 현재 테이블에있는 데이터를 변환 할 수 있는지 여부에 관계없이 변경하지 마십시오. 데이터 손실.
이 있습니까 어떤 가까운 장래에이 데이터를 채우기 위해 추가 소스를 추가 관련 계획 / 토론?
그리고 관련 질문을 추가합니다 :이나요되어 현재의 소스 테이블 (즉, 여러 언어를 지원 주위에 어떤 논의 [Q].[G]
변환) 를 에 NVARCHAR
?
이러한 가능성에 대한 이해를 얻으려면 주변에 문의해야합니다. 나는 현재 당신이이 방향을 가리키는 어떤 말도하지 않았다고 가정합니다. 그렇지 않으면 당신은이 질문을하지 않을 것입니다. 가장 정확하고 완전한 답변을 얻을 수있는 충분한 청중.
여기서 주요 문제는 변환 할 수없는 유니 코드 코드 포인트가 아니라 단일 코드 페이지에 모두 맞지 않는 코드 포인트가 있다는 것입니다. 이것이 유니 코드의 좋은 점입니다. 모든 코드 페이지의 문자를 보유 할 수 있습니다. NVARCHAR
코드 페이지에 대해 걱정할 필요가없는 곳에서로 변환하는 경우 VARCHAR
대상 열의 데이터 정렬이 소스 열과 동일한 코드 페이지를 사용하고 있는지 확인해야합니다. 이것은 하나의 소스 또는 동일한 코드 페이지를 사용하는 여러 소스를 가지고 있다고 가정합니다 (그렇지만 반드시 동일한 데이터 정렬은 아님). 그러나 코드 페이지가 여러 개인 소스가 여러 개인 경우 다음과 같은 문제가 발생할 수 있습니다.
DECLARE @Reporting TABLE
(
ID INT IDENTITY(1, 1) PRIMARY KEY,
SourceSlovak VARCHAR(50) COLLATE Slovak_CI_AS,
SourceHebrew VARCHAR(50) COLLATE Hebrew_CI_AS,
Destination NVARCHAR(50) COLLATE Latin1_General_CI_AS,
DestinationS VARCHAR(50) COLLATE Slovak_CI_AS,
DestinationH VARCHAR(50) COLLATE Hebrew_CI_AS
);
INSERT INTO @Reporting ([SourceSlovak]) VALUES (0xDE20FA);
INSERT INTO @Reporting ([SourceHebrew]) VALUES (0xE820FA);
UPDATE @Reporting
SET [Destination] = [SourceSlovak]
WHERE [SourceSlovak] IS NOT NULL;
UPDATE @Reporting
SET [Destination] = [SourceHebrew]
WHERE [SourceHebrew] IS NOT NULL;
SELECT * FROM @Reporting;
UPDATE @Reporting
SET [DestinationS] = [Destination],
[DestinationH] = [Destination]
SELECT * FROM @Reporting;
반환 (두 번째 결과 집합) :
ID SourceSlovak SourceHebrew Destination DestinationS DestinationH
1 Ţ ú NULL Ţ ú Ţ ú ? ?
2 NULL ט ת ? ? ט ת ט ת
보다시피, 모든 문자 는VARCHAR
같은 VARCHAR
열이 아닌 로 변환 될 수 있습니다 .
다음 쿼리를 사용하여 소스 테이블의 각 열에 대한 코드 페이지를 확인하십시오.
SELECT OBJECT_NAME(sc.[object_id]) AS [TableName],
COLLATIONPROPERTY(sc.[collation_name], 'CodePage') AS [CodePage],
sc.*
FROM sys.columns sc
WHERE OBJECT_NAME(sc.[object_id]) = N'source_table_name';
안전합니다 ....
그러나 SQL Server 2008 R2에 대해 언급했지만 어떤 에디션도 말하지 않았습니다. Enterprise Edition을 사용하는 경우 공간을 절약하기 위해이 변환 작업을 모두 잊고 데이터 압축을 활성화하십시오.
유니 코드 압축 구현
Standard Edition을 사용하는 경우 (그리고 현재는 😞), 또 다른 looooong-shot 가능성이 있습니다. SP1부터 모든 Edition이 데이터 압축을 사용할 수있는 기능이 포함되어 있기 때문에 SQL Server 2016으로 업그레이드 할 수 있습니다. "😉).
물론 데이터에 대한 소스가 하나뿐이라는 사실이 밝혀 졌으므로 소스에 유니 코드 전용 문자 또는 특정 코드 외부의 문자를 포함 할 수 없으므로 걱정할 필요가 없습니다. 페이지. 이 경우주의해야 할 유일한 것은 소스 열과 동일한 데이터 정렬 또는 동일한 코드 페이지를 사용하는 데이터 정렬을 사용하는 것입니다. 소스 열 에서를 SQL_Latin1_General_CP1_CI_AS
사용 Latin1_General_100_CI_AS
하는 경우 대상에서 사용할 수 있습니다 .
사용할 데이터 정렬을 알고 나면 다음 중 하나를 수행 할 수 있습니다.
ALTER TABLE ... ALTER COLUMN ...
수 VARCHAR
(현재 지정해야합니다 NULL
/ NOT NULL
약간의 시간과 8,700 만 행에 대한 트랜잭션 로그 공간을 많이 필요로 설정), OR
각각의 새로운 "ColumnName_tmp"열을 만들고 천천히 통해 채우는 UPDATE
일 TOP (1000) ... WHERE new_column IS NULL
. 명시 적 트랜잭션에서 모든 행이 채워지고 (모든 행이 올바르게 복사되었는지 확인한 경우 UPDATE를 처리하기 위해 트리거가 필요할 수 있습니다.), 명시 적 트랜잭션 sp_rename
에서 "현재"열의 열 이름을 " _Old "다음에 새"_tmp "열을 사용하여 이름에서"_tmp "를 간단히 제거하십시오. 그런 다음 sp_reconfigure
테이블을 호출 하여 테이블을 참조하는 캐시 된 계획을 무효화하고 테이블을 참조하는 뷰가 있으면 호출해야합니다 sp_refreshview
(또는 이와 유사한 것). 앱의 유효성을 검사하고 ETL이 올바르게 작동하면 열을 삭제할 수 있습니다.
[G]
에 ETL됩니다[P]
. 경우[G]
이며varchar
, 그리고 ETL 프로세스로 데이터를 제공하는 유일한 방법입니다[P]
, 프로세스가 진정한 유니 코드 문자를 추가 한 후 언급되어 있지 않는 한,이 안된다. 다른 프로세스가에 데이터를 추가 또는 수정[P]
하는 경우 현재 데이터가 모두 내일 추가 될 수 없다는varchar
의미는 아니기 때문에 더주의해야합니다nvarchar
. 마찬가지로, 데이터를 소비하는 모든 데이터에 데이터가[P]
필요할nvarchar
수 있습니다.