2014-01-24 5 views
15

임시 테이블을 업데이트 할 수 없습니다. 이것은 내 쿼리임시 테이블 정렬 충돌 - 오류 : Latin1 *과 SQL_Latin1 간의 데이터 정렬 충돌을 해결할 수 없습니다.

CREATE TABLE #temp_po(IndentID INT, OIndentDetailID INT, OD1 VARCHAR(50), OD2 VARCHAR(50), 
     OD3 VARCHAR(50), ORD VARCHAR(50), NIndentDetailID INT, ND1 VARCHAR(50), ND2 VARCHAR(50), 
     ND3 VARCHAR(50), NRD VARCHAR(50), Quantity DECIMAL(15,3)) 

     INSERT INTO #temp_po(IndentID, OIndentDetailID, OD1, OD2, OD3, ORD) 
     SELECT ID.IndentID, ID.IndentDetailID, ID.D1, ID.D2, ID.D3, ID.RandomDimension 
     FROM STR_IndentDetail ID WHERE ID.IndentID = @IndentID 

     UPDATE 
      t 
     SET 
      t.ND1 = CASE WHEN D.D1 = '' THEN NULL ELSE D.D1 END, 
      t.ND2 = CASE WHEN D.D2 = '' THEN NULL ELSE D.D2 END, 
      t.ND3 = CASE WHEN D.D3 = '' THEN NULL ELSE D.D3 END, 
      t.NRD = CASE WHEN D.RandomDim = '' THEN NULL ELSE D.RandomDim END, 
      t.Quantity = D.PurchaseQty 
     FROM 
      #temp_po t INNER JOIN @detail D ON D.IndentDetailID = t.OIndentDetailID 
     WHERE 
      t.IndentID = @IndentID 

이다 그러나 "Latin1_General_CI_AI"및 운영에 동일한에서 "SQL_Latin1_General_CP1_CI_AS 데이터"간의 데이터 정렬 충돌을 해결할 수 없습니다 오류

을 제공합니다.

이 문제를 해결하는 방법?

tempdb 데이터 정렬은 Latin1_General_CI_AI이고 실제 데이터베이스 정렬은 SQL_Latin1_General_CP1_CI_AS입니다.

+2

이 마스터 DB의 정렬에 tempdb의 디폴트 이후 열 (가능성이 데이터베이스에서 상속) 조합과 마스터 사이의 충돌, 아래 말했다. 가장 쉬운 해결책은 각 (n) char/(n) varchar 데이터 유형에 COLLATE DATABASE_DEFAULT를 추가하여 작업중인 데이터베이스와 일치하도록 임시 테이블이 항상 만들어 지도록하는 것입니다. – Kahn

답변

25

#tempdb.temp_po.OD1STR_IndentDetail.D1의 데이터 정렬이 서로 다르기 때문에 이러한 현상이 발생합니다.

CREATE TABLE #temp_po(
    IndentID INT, 
    OIndentDetailID INT, 
    OD1 VARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS, 
    .. Same for the other *char columns 

: 당신이 임시 테이블의 생성을 제어 할 수 있기 때문에

,이 문제를 해결하는 가장 쉬운 방법은 STR_IndentDetail 테이블과 같은 데이터 정렬 * 임시 테이블의 문자 열을 생성하는 것으로 보인다 당신이 열을 조인 할 때 테이블 생성을 제어 할 수없는 상황에서, 또 다른 방법은 사용 중 COLLATE SQL_Latin1_General_CP1_CI_AS 또는 쉽게를 통해 오류가 발생하는 DML에 명시 적 COLLATE 문을 추가하는 것입니다 COLLATE DATABASE_DEFAULT

SELECT * FROM #temp_po t INNER JOIN STR_IndentDetail s 
    ON t.OD1 = s.D1 COLLATE SQL_Latin1_General_CP1_CI_AS; 
기본 임시 테이블에 의해

OR, 쉽게

SELECT * FROM #temp_po t INNER JOIN STR_IndentDetail s 
    ON t.OD1 = s.D1 COLLATE DATABASE_DEFAULT; 

SqlFiddle here

+0

관련 기사는 여기 http://www.mssqltips.com/sqlservertip/2440/create-sql-server-temporary-tables-with-the-correct-collation/ –

0

서버의 데이터 정렬을. 그래서 temp 테이블로 모든 저장 프로 시저를 업데이트하면 서버 데이터 정렬 만 변경됩니다.

점검 Set or Change the Server Collation

이 링크이 나를 위해 일했다.

0

지금 같은 문제가 발생했습니다. 임시 테이블 생성 (또는 각 임시 테이블 조인)에 데이터 정렬을 추가하는 대신 임시 테이블 생성을 테이블 변수 선언으로 변경했습니다.

1

서버 정렬을 변경하는 것은 직접적인 결정이 아니므로 서버에 영향을 줄 수있는 다른 데이터베이스가있을 수 있습니다. 데이터베이스 데이터 정렬을 변경하는 것만으로는 기존의 채워진 데이터베이스에 항상 적합한 것은 아닙니다. 나는 temp 테이블을 만들 때 COLLATE DATABASE_DEFAULT을 사용하는 것이 SQL에서 임의의 데이터 정렬을 하드 코딩하지 않기 때문에 가장 안전하고 쉬운 옵션이라고 생각합니다. 예를 들어 : @StuartLC으로

CREATE TABLE #temp_table1 
(
    column_1 VARCHAR(2) COLLATE database_default 
)