[sql-server] 동일 작업에서“SQL_Latin1_General_CP1_CI_AS”와“Latin1_General_CI_AS”의 데이터 정렬 충돌을 해결할 수 없습니다.

다음 코드가 있습니다

SELECT tA.FieldName As [Field Name],
       COALESCE(tO_A.[desc], tO_B.[desc], tO_C.Name, tA.OldVAlue) AS [Old Value],
       COALESCE(tN_A.[desc], tN_B.[desc], tN_C.Name, tA.NewValue) AS [New Value],
       U.UserName AS [User Name],
       CONVERT(varchar, tA.ChangeDate) AS [Change Date]
  FROM D tA
       JOIN
       [DRTS].[dbo].[User] U
         ON tA.UserID = U.UserID
       LEFT JOIN
       A tO_A
         on tA.FieldName = 'AID'
        AND tA.oldValue = CONVERT(VARCHAR, tO_A.ID)
       LEFT JOIN
       A tN_A
         on tA.FieldName = 'AID'
        AND tA.newValue = CONVERT(VARCHAR, tN_A.ID)
       LEFT JOIN
       B tO_B
         on tA.FieldName = 'BID'
        AND tA.oldValue = CONVERT(VARCHAR, tO_B.ID)
       LEFT JOIN
       B tN_B
         on tA.FieldName = 'BID'
        AND tA.newValue = CONVERT(VARCHAR, tN_B.ID)
       LEFT JOIN
       C tO_C
         on tA.FieldName = 'CID'
        AND tA.oldValue = tO_C.Name
       LEFT JOIN
       C tN_C
         on tA.FieldName = 'CID'
        AND tA.newValue = tN_C.Name
 WHERE U.Fullname = @SearchTerm
ORDER BY tA.ChangeDate

코드를 실행할 때 표 C에 두 개의 조인을 추가 한 후 제목에 오류가 붙여졌습니다. SQL Server 2008을 사용하고 있다는 사실과 관련이있을 수 있습니다. 내 기계는 2005입니다.



답변

테이블에 서로 다른 두 데이터 정렬이 일치하지 않습니다. 이 쿼리를 사용하여 테이블의 각 열에 어떤 데이터 정렬이 있는지 확인할 수 있습니다.

SELECT
    col.name, col.collation_name
FROM
    sys.columns col
WHERE
    object_id = OBJECT_ID('YourTableName')

문자열을 주문하고 비교할 때 데이터 정렬이 필요하고 사용됩니다. 일반적으로 데이터베이스 전체에서 하나의 고유 한 데이터 정렬을 사용하는 것이 좋습니다. 단일 테이블이나 데이터베이스 내에서 다른 데이터 정렬을 사용하지 마십시오. 문제가있을뿐입니다 ….

하나의 단일 데이터 정렬을 설정 한 후에는이 명령을 사용하여 아직 일치하지 않는 테이블 / 열을 변경할 수 있습니다.

ALTER TABLE YourTableName
  ALTER COLUMN OffendingColumn
    VARCHAR(100) COLLATE Latin1_General_CI_AS NOT NULL

마크

업데이트 : 데이터베이스에서 전체 텍스트 인덱스를 찾으려면 다음 쿼리를 사용하십시오.

SELECT
    fti.object_Id,
    OBJECT_NAME(fti.object_id) 'Fulltext index',
    fti.is_enabled,
    i.name 'Index name',
    OBJECT_NAME(i.object_id) 'Table name'
FROM
    sys.fulltext_indexes fti
INNER JOIN
    sys.indexes i ON fti.unique_index_id = i.index_id

그런 다음 다음을 사용하여 전체 텍스트 인덱스를 삭제할 수 있습니다.

DROP FULLTEXT INDEX ON (tablename)


답변

나는 다음을한다 :

...WHERE
    fieldname COLLATE DATABASE_DEFAULT = otherfieldname COLLATE DATABASE_DEFAULT

매번 작동합니다. 🙂


답변

collate쿼리 에서 절을 사용하십시오 .

LEFT JOIN C tO_C on tA.FieldName = 'CID' AND tA.oldValue COLLATE Latin1_General_CI_AS = tO_C.Name  

구문이 정확하지 않을 수도 있지만 (BOL 확인) 쿼리의 데이터 정렬을 즉시 변경하려면이 작업을 수행 할 수 있습니다-각 조인에 대한 절을 추가해야 할 수도 있습니다.

편집 : 나는 이것이 옳지 않다는 것을 깨달았습니다-collate 절은 변경 해야하는 필드 뒤에옵니다-이 예에서는 tA.oldValue필드 의 데이터 정렬을 변경했습니다 .


답변

이 오류가 발생하는 필드를 식별하고 다음을 추가하십시오. COLLATE DATABASE_DEFAULT

코드 필드에는 두 개의 테이블이 결합되어 있습니다.

...
and table1.Code = table2.Code
...

다음과 같이 쿼리를 업데이트하십시오.

...
and table1.Code COLLATE DATABASE_DEFAULT = table2.Code COLLATE DATABASE_DEFAULT
...


답변

서로 다른 2 개의 데이터베이스와 2 개의 다른 서버에서 특별히 2 개의 다른 데이터베이스가있을 때 쉽게 발생할 수 있습니다. 가장 좋은 방법은 공통 모음으로 변경하고 조인 또는 비교를 수행하는 것입니다.

SELECT
   *
FROM sd
INNER JOIN pd ON sd.SCaseflowID COLLATE Latin1_General_CS_AS = pd.PDebt_code COLLATE Latin1_General_CS_AS


답변

@Valkyrie 멋진 답변. 저장 프로 시저 내부의 하위 쿼리를 사용하여 동일한 작업을 수행 할 때 여기에 사례를 넣었습니다.이 경우 귀하의 답변이 효과가 있는지 궁금해했습니다.

...WHERE fieldname COLLATE DATABASE_DEFAULT in (
          SELECT DISTINCT otherfieldname COLLATE DATABASE_DEFAULT
          FROM ...
          WHERE ...
        )


답변

어디에 기준을 추가 collate SQL_Latin1_General_CP1_CI_AS

이것은 나를 위해 작동합니다.

WHERE U.Fullname = @SearchTerm  collate SQL_Latin1_General_CP1_CI_AS