Sql-Server

如何在 SQL Server 中加入全域臨時表?

  • June 11, 2020

我有四個全域臨時表(##A,##B,##C,##D),我想left join在 SQL Server 2008 中對其執行。通過全域臨時表,我的意思是我使用如下程式碼創建了它們:

SELECT *
INTO ##A

這四個表都有一個具有相同名稱“鍵”的列,我想使用該列執行連接。我正在使用這個邏輯:

SELECT * 
INTO ##X
FROM ##A as a
LEFT JOIN ##B as b ON a.key = b.key
LEFT JOIN ##C as c ON a.key = c.key
LEFT JOIN ##D as d on a.key = d.key

當我執行此程式碼時,我收到以下錯誤:

無法解決等於操作中“Latin1_General_100_BIN”和“SQL_Latin1_General_CP1_CI_AS”之間的排序規則衝突。

我一直被困在這裡,似乎無法解決它。

非常感謝任何幫助/建議/建議。

雖然另一個答案(即“使用COLLATE DATABASE_DEFAULT”)似乎在這里工作,甚至可能在許多其他情況下工作,但它並沒有真正解決這個問題,實際上對一些讀者來說是個壞建議。

這個問題的根本問題是:

  1. 正在對字元串列進行 JOIN,並且
  2. 在被 JOINed 的那些字元串列中使用了多個排序規則

無論表的類型如何(永久、局部臨時、全域臨時、表變數等),在操作中混合多個字元串(即謂詞、連接UNION等)時,它們之間的排序規則必須

  1. 相同(對於任何不能強制進入另一個排序規則的東西),或者
  2. 強制轉換為另一個排序規則

列排序規則是不可強制的,而字元串文字和變數是。此問題處理字元串列之間的 JOIN,因此它們都不是可強制的,因此它們都需要是相同的排序規則,否則您會得到問題中顯示的“無法解決排序規則衝突”錯誤。

解決這個問題確實需要使用可選COLLATE子句,但我不建議DATABASE_DEFAULT在這種情況下使用。該DATABASE_DEFAULT選項僅使用執行查詢的目前數據庫的排序規則。該排序規則不一定是這四個全域臨時表中任何列的排序規則。四個基本全域臨時表(、、、和)中的列的##A排序規則是通過創建這些全域臨時表時源表中的排序規則。這與使用的實例級預設排序規則無關,因為這些臨時表不是通過創建的(其中字元串列未指定子句)。##B``##C``##D``SELECT * INTO...``tempdb``CREATE TABLE ##....``COLLATE

在這種情況下,數據庫級別的預設排序規則既不知道也不被使用,最好在您想要使用的排序規則中有意/明確地使用。錯誤中提到了兩個排序規則:Latin1_General_100_BINSQL_Latin1_General_CP1_CI_ASCOLLATE根據此查詢的意圖,為子句選擇其中一個。這些 JOIN 是否需要不區分大小寫,或者 JOIN 列是否需要相同(即二進制比較)?假設您需要相同的值,請執行以下操作:

SELECT * 
INTO ##X
FROM ##A as a
LEFT JOIN ##B as b ON a.key = b.key COLLATE Latin1_General_100_BIN
LEFT JOIN ##C as c ON a.key = c.key COLLATE Latin1_General_100_BIN
LEFT JOIN ##D as d on a.key = d.key COLLATE Latin1_General_100_BIN;

或者,根據這些表之間的關係如何工作,您甚至可以使用不同的排序規則來更好地匹配不同表之間的不同關係:

SELECT * 
INTO ##X
FROM ##A as a
LEFT JOIN ##B as b ON a.key = b.key COLLATE Latin1_General_100_BIN
LEFT JOIN ##C as c ON a.key = c.key COLLATE SQL_Latin1_General_CP1_CI_AS
LEFT JOIN ##D as d on a.key = d.key COLLATE Latin1_General_100_BIN;

引用自:https://dba.stackexchange.com/questions/222179