“ 문자열 또는 바이너리 데이터가 잘리는 열을 식별하려면 어떻게해야합니까? ”

원격 Pg 데이터베이스에서 SELECT에 작성한 코드를 사용하여 일부 쿼리를 자동으로 생성하고 로컬 SQL Server 데이터베이스에 삽입합니다. 그러나 그중 하나가 다음 오류를 생성합니다.

[Microsoft] [ODBC SQL Server Driver] [SQL Server] 문자열 또는 이진 데이터가 잘립니다. (SQL-22001) [state was 22001 now 01000]

[Microsoft] [ODBC SQL Server Driver] [SQL Server] 문이 종료되었습니다. (SQL-01000) at. \ insert.pl line 106.

어떤 열이 해당 오류를 생성하고 길이가 부족한지 어떻게 알 수 있습니까? 입력? 모든 varchar를 무차별 적으로 추측하지 않고이를 수행 할 수있는 방법이 있습니까?

답변

아니요, 어디에도 기록되지 않습니다. 투표하고 비즈니스 사례를 진술하십시오. 이것은 SQL Server에서 수정해야하는 긴 목록 중 하나입니다.

이것은 수년 전에 Connect에서 요청한 것입니다 (아마도 SQL Server 2000 또는 2005 기간 중 처음), 그리고 다시 새로운 피드백 시스템 :

이제 다음 버전으로 제공되었습니다.

SQL Server 2019의 최초 공개 CTP에서는 추적 플래그 460 아래에만 표시됩니다. 이것은 일종의 비밀로 들리지만 이 Microsoft 백서 . 이는 앞으로의 기본 동작 (추적 플래그 필요 없음)이되지만 새로운 데이터베이스 범위 구성 VERBOSE_TRUNCATION_WARNINGS을 통해이를 제어 할 수 있습니다.

여기 예 :

USE tempdb; GO CREATE TABLE dbo.x(a char(1)); INSERT dbo.x(a) VALUES("foo"); GO 

SQL Server 2019 이전에 지원되는 모든 버전의 결과 :

Msg 8152, Level 16, State 30, Line 5
문자열 또는 이진 데이터가 잘립니다.
문이 종료되었습니다.

이제 SQL Server 2019 CTP에서 추적 플래그가 활성화되었습니다.

DBCC TRACEON(460); GO INSERT dbo.x(a) VALUES("foo"); GO DROP TABLE dbo.x; DBCC TRACEOFF(460); 

결과에 표, 열 및 ( 잘린 이 표시되지 않고 전체 ) 값 :

Msg 2628, 레벨 16, State 1, Line 11
문자열 또는 이진 데이터는 테이블 “tempdb.dbo.x”, 열 “a”에서 잘립니다. 잘린 값 : “f”.
문이 종료되었습니다.

지원되는 버전 / CU로 이동하거나 Azure SQL Database로 이동할 수있을 때까지 “automagic”코드는 실제로 sys.columns에서 max_length를 가져와야하는 이름과 함께 가져 와서 LEFT(column, max_length)를 적용합니다. 또는 그에 상응하는 PG가 무엇이든 상관 없습니다. 또는 “조용히 데이터가 손실 될 것이므로 일치하지 않는 열을 찾아서 소스의 모든 데이터에 맞도록 대상 열을 수정하십시오. 두 시스템에 대한 메타 데이터 액세스 및 소스-> 대상 열과 자동으로 일치해야하는 쿼리를 이미 작성하고 있다는 사실 (그렇지 않으면이 오류가 가장 큰 문제가되지 않음)을 감안할 때 무차별 대입을 수행 할 필요가 없습니다.

답변

SQL Server 가져 오기 및 내보내기 마법사 를 실행할 권한이있는 경우 SQL Server Management Studio (데이터베이스를 마우스 오른쪽 단추로 클릭> 작업> 데이터 가져 오기 …)에서 쿼리를 데이터 원본으로 사용하여 대상 테이블로 가져 오는 작업을 만듭니다.

가져 오기를 실행하기 전에 데이터 매핑을 검토하면 일치하지 않는 필드 유형이있는 열을 확인할 수 있습니다. 가져 오기 작업을 실행하면 가져 오기에 실패한 열이 표시됩니다.

샘플 유효성 검사 경고 :

경고 0x802092a7 : 데이터 흐름 작업 1 : 길이가 316 인 데이터 흐름 열 “NARRATIVE”에서 길이가 60 인 데이터베이스 열 “NARRATIVE”에 데이터를 삽입하면 잘림이 발생할 수 있습니다. (SQL Server 가져 오기 및 내보내기 마법사)

답변

마지막으로 Microsoft SQL Server 2016 SP2 CU, SQL Server 2017 CU12 및 SQL Server 2019부터 String or binary would be truncated에 대해 의미있는 정보를 제공하기로 결정했습니다 .

정보 이제 문제가되는 테이블 열 (정규화 된 이름)과 문제가되는 값 (120 자에서 잘림)이 모두 포함됩니다.

Msg 2628, Level 16, State 1, 줄 x 문자열 또는 이진 데이터는 “TheDb.TheSchema.”테이블에서 잘립니다.TheTable “,”TheColumn “열. 잘린 값 :”… “. 구문이 종료되었습니다.

Answer

결국 열 정보를 직접 작성하지 않고는 가져올 수 없습니다.

이 오류 메시지는 DBD::ODBC , 그러나 sys.columns (max_length)를 사용할 수도 있습니다 (방법은 모르겠습니다).

COLUMN_NAMEMAX_LENGTH라는 두 요소가있는 배열 목록을 가져 오기 위해 열 목록에 이와 같은 코드를 사용했습니다. div> ( DBI column_info() 에 문서화 됨)

my @max_lengths = map [ @{$_->fetchall_arrayref->[0]}[3,6] ] , map $dbh_mssql->column_info("database", "dbo", $dest_table, $_) , @col_mssql ; 

그런 다음 INSERT에서 예외를 포착하고 유용한 것을 인쇄했습니다. 이 예에서 @$rowsth->execute()

if ($@) { warn "$@\n"; for ( my $idx=0; $idx <= $#{ $row }; $idx++ ) { Dumper { maxlength => $max_lengths[$idx]->[1] , name => $max_lengths[$idx]->[0] , length => length( $row->[$idx] ) , content => $row->[$idx] }; } die; } 

또한 다른 답변에 투표하고 찬성 해주세요.

댓글

  • I ' sys.columns를 참조하는 코드를 넣지 않았습니다. 현재 자동으로 " 쿼리를 생성합니다. ' 코드에 통합하는 것이 SELECT name, object_id, max_length FROM sys.columns;보다 훨씬 복잡하지 않습니다. 이 작업을 수행해야하는 automagic 코드 또는 이와 유사한 코드가 이미 있으므로 ' 예제가 필요하다고 생각하지 않았습니다.
  • 저 ' sys.columns가 동일한 name를 가진 두 개의 열에서 어떻게 작동하는지 잘 모르겠습니다. 또한 sys 대신 라이브러리를 사용하여 작동하는 것을 얻었습니다. 왜 내가 선택한 답변으로 만들까요? Microsoft SQL doesn't have x, do y instead는 유효한 기부이지만 y가 내 y보다 열등하다면 ' 다른 작업을 수행하고 선택한 것으로 표시하겠습니다.
  • 귀하의 질문은 기본적으로 어떤 열에서 오류가 발생했는지 어떻게 알 수 있는지 (아마도 , 솔루션을 재 설계하는 대신 한 지점을 수정할 수 있습니다.) sys.columns를 살펴 보도록하겠습니다. 소스 열 길이와 대상 열 길이를 비교하기 위해 정확히 찾아야합니다. 그 방법은 당신에게 달려 있습니다. 저는 ' 코드를 수정하는 방법을 알려주지 않았습니다. 처음에 자동 매직 쿼리가 어떻게 생성되는지 전혀 몰랐기 때문에 제가 말했듯이 어떻게 이미 가지고있는 쿼리에 길이 결정을 추가합니다.

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다