這是在預儲程序後執行時所回應的錯誤訊息,程式碼節錄部份如下:

1
2
3
4
5
6
7
CREATE TABLE #tbMain(id INT IDENTITY(1,1), Line VARCHAR(20) NOT NULL, Part_num VARCHAR(9) NOT NULL, Lv INT)

INSERT INTO #tbMain(Line,Part_num,Lv)
SELECT Replicate('.',@L) + LTrim(str(@L)), B.Part_num, @L+1
FROM BOM B, #tbMain M
WHERE B.Asmb_num = M.Part_num
  AND M.Lv = @L

為什麼呢?
一般繁體中文版 MSSQL 建置時多數人都會用預設定序 Chinese_Taiwan_Stroke_CI_AS
但是其中一個資料庫是從別的環境附加進來的,該資料庫定序是用 Chinese_Taiwan_Stroke_BIN
一般來說,在同一個資料庫中的資料表的定序都會使用資料庫預設值
此問題常發生於處理兩個資料庫的資料表進行 JOIN 關聯之時
而建立臨時表 #tbMain 會使用 TempDB 資料庫的空間與定序
而 TempDB 資料庫的定序使用伺服器的定序設定
所以當 JOIN 這兩個不同定序的資料表時,字串欄位就無法進行比對而回應錯誤

可以將程式碼中的

1
WHERE B.Asmb_num = M.Part_num

改成

1
WHERE B.Asmb_num COLLATE Chinese_Taiwan_Stroke_BIN = M.Part_num COLLATE Chinese_Taiwan_Stroke_BIN

強制轉換成為相同定序後就可以正常執行了

另外因為本狀況是使用臨時表,所以也可以在建立時就指定欄位定序

1
2
3
4
5
CREATE TABLE #tbMain(
id INT IDENTITY(1,1),
Line VARCHAR(20) COLLATE Chinese_Taiwan_Stroke_BIN NOT NULL,
Part_num VARCHAR(9) COLLATE Chinese_Taiwan_Stroke_BIN NOT NULL,
Lv INT)

這樣就不必在每個 JOIN 指令中強制轉換定序
不過最好還是將資料庫轉換成與伺服器相同的定序