Ошибка сопоставления столбцов Temp - Ошибка: не удается разрешить конфликт сортировки между латинскими * и SQL_Latin1 *

Я не могу обновить таблицу temp. Это мой запрос

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.

Ответ 1

Это происходит потому, что сортировки на #tempdb.temp_po.OD1 и STR_IndentDetail.D1 различны.

Поскольку у вас есть контроль над созданием таблицы temp, самым простым способом решения этой проблемы является создание столбцов * char в таблице temp с тем же сопоставлением, что и таблица STR_IndentDetail:

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

В ситуации, когда вы не контролируете создание таблицы, когда вы присоединяетесь к столбцам, другим способом является добавление явных инструкций COLLATE в DML, где происходят ошибки, либо через COLLATE SQL_Latin1_General_CP1_CI_AS, либо проще, используя 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;

ИЛИ, проще

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

SqlFiddle здесь

Ответ 2

По умолчанию в таблице temp выполняется сортировка сервера. Поэтому вместо обновления всей хранимой процедуры с помощью таблицы temp изменяется только сортировка сервера.

Отметьте эту ссылку для Установить или изменить сортировку сервера

Это сработало для меня.

Ответ 3

Мы столкнулись с той же проблемой прямо сейчас. Вместо добавления сопоставления в создание таблицы temp (или для каждого соединения temp table) мы просто изменили создание таблицы temp на объявление переменной таблицы.

Ответ 4

Изменение сортировки сервера не является прямым решением, на сервере могут быть другие базы данных, на которые может повлиять. Даже изменение сортировки базы данных не всегда желательно для существующей заполненной базы данных. Я думаю, что использование COLLATE DATABASE_DEFAULT при создании temp-таблицы - самый безопасный и простой вариант, поскольку он не содержит жестких кодов для сортировки в вашем sql. Например:

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