Sql-Server

在將數據從腳本載入到 SQL 時處理數據編碼問題 (Notepad++)

  • June 21, 2019

我很確定這不是 SQL Server 問題。

我已經在這裡提出了一個很棒的解釋的問題,但是我仍然無法向我工作的人解釋它與 SQL Server 排序規則等無關。

情況:

我們使用 ANSI 創建腳本 ( INSERTS/DELETS )。我們將這些腳本發送給我們的客戶。Out 客戶端通過 SQLPLUS、SSMS 或任何其他方法執行這些腳本。

當他們使用使用 ANSI 的東西時,沒有問題。

但是我們想強制一些事情,告訴他們類似“嘿,你正在使用不同的編碼執行這個腳本,並且一些字元的格式會很舊,ã就像xE3.

有沒有辦法強制腳本在其本機編碼(我創建的編碼)上執行?

我真的不知道如何解決這個問題。我們想發送一個腳本,並且我們想確保這個腳本將在 A 為 A、Ã 為 Ã 的情況下執行。

一種選擇可能是讓他們通過帶有程式碼頁選項的 sqlcmd 執行腳本:

sqlcmd -f <codepage> | i:<codepage>,o:<codepage>

或者,使用 UTF-8 編碼(程式碼頁 65001)保存源文件,並帶有字節順序標記。

正如我在您在問題中連結到的先前答案中所建議的那樣,腳本將自己標識為特定編碼的唯一方法是使用字節順序標記 (BOM)。這僅適用於 Unicode 編碼。

  • 如果您使用的是 SSMS,請打開“另存為…”對話框,下拉按鈕右側的箭頭Save ▼,選擇“使用編碼保存…”,然後在“編碼”下拉菜單中,選擇“Unicode(帶簽名的UTF-8)-程式碼頁65001”(朝向列表頂部)。
  • 如果您在 Notepad++ 中創建腳本(在此問題的標題中註明),請轉到“編碼”菜單並選擇“在 UTF-8-BOM 中編碼”。

設置字節順序標記至少允許讀取文件的程序檢測編碼。這並不能保證腳本會在讀取 BOM 的程序中打開或被讀取,但如果客戶端使用 SSMS 或 Notepad++,不確定 SQLPLUS(多年未使用),那麼這些程序確實可以正確檢測 BOM。

當然,如果讀取具有 BOM 的文件的程序沒有檢測到 BOM,那麼腳本一開始可能會有 2 或 3 個“奇怪”字元。這些是檢測 BOM 的程序刪除的字節順序標記字元。

除此之外,還有一些其他的想法需要考慮:

  1. 我認為您可以通過將保存為自身的補充字元與 SQL Server 生成的相同字元進行比較,讓腳本本身檢測它是否以正確的編碼打開。當腳本保存為 UTF-8 時,該字元的字節序列為0xF09F9983. 如果腳本以 UTF-8 格式打開,您將看到:“🙃”。但是,如果腳本以“ANSI”打開,您將看到:“🙃”。如果字元不正確,您可以列印錯誤並關閉執行:
-- top of script
IF (N'🙃' <> NCHAR(0xD83D) + NCHAR(0xDE43))
BEGIN
 RAISERROR('
   This script is encoded in UTF-8 but has been opened using a non-UTF-8 encoding.
   Please re-open this script either as UTF-8, or try switching the encoding
   to UTF-8 if that is an option.', 16, 1);
 SET NOEXEC ON;
END;

-- the next line is for testing; just to prove that execution is OFF
PRINT 5;
-- stuffs



-- at the very end of the script
GO
SET NOEXEC OFF;
-- the next line is for testing; just to prove that execution is back ON
PRINT 6;
GO

要查看我從哪裡獲得字節序列,只需查看https://unicode-table.com/en/1F643/底部有一個圖表。UTF-16BE 十六進制列表是您想要的NCHAR(0x....) + NCHAR(0x....) 2. 由於這是字元串數據,因此可以以不需要任何特定編碼的“安全”格式對其進行編碼。我會根據情況使用以下任一技巧:

  1. 對於這里和那裡的幾個非 ANSI 字元,您可以單獨執行它們:
SELECT UNICODE(N'Ã'); -- 195

SELECT N'start of txt' + NCHAR(195) + N'more text';
 對於許多字元,只需將字元串轉換為其二進製表示:
LECT CONVERT(VARBINARY(MAX), N'start of txt' + NCHAR(195) + N'more');
  0x7300740061007200740020006F0066002000740078007400C3006D006F0072006500

SERT INTO dbo.SomeTable (columnName)
LUES (CONVERT(NVARCHAR(100), 
7300740061007200740020006F0066002000740078007400C3006D006F0072006500);

個十六進製表示可以連接成正常字元串值:
LUES (N'some text' + CONVERT(NVARCHAR(50), 0x73007400610072007400...)
N'more text')


我不確定如何為 Oracle 實現這些想法,但概念應該是相同的。

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