Sql-Server

通過 Power shell 執行 TSQL 腳本,特殊字元呈現問題

  • August 16, 2018

我們有一個簡單的 T-SQL 腳本文件 (.sql),我們通過 Powershell 執行它。一切正常,除了腳本部分,我們使用一些特殊字元作為字元串(例如:‘ô’)。

如果我只是通過 SQL Server Management Studio 執行它,相同的腳本可以正常工作,但通過 Powershell 它不能正確呈現這些特殊字元。

這裡我們如何訪問腳本文件以在實例上的所有數據庫上執行

Add-PSSnapin SqlServerCmdletSnapin100
Add-PSSnapin SqlServerProviderSnapin100
invoke-Sqlcmd -InputFile "C:\DailyPatch\run.sql" | Out-File -filePath "C:\DailyPatch\dbname.txt" 
$text=Get-Content C:\DailyPatch\dbname.txt
$a = $text.length
$a=$a-3

$logFile = 'C:\DailyPatch\dblog.txt'

for ($i=3 ; $i -le $a ;$i++)
{   
   write-host $text[$i]
   $error.clear()

   Invoke-sqlcmd -inputfile "C:\DailyPatch\Script4AllDBs.sql"-database $text[$i]-OutputSqlErrors $true|Out-File -filePath "C:\DailyPatch\dbname.txt"

   foreach ($rr in $error) {
       $text[$i] >> $logFile
       $rr >> $logFile
   }
}

如何在 Powershell 中設置排序規則以避免此類問題?

附言。Unicode 的東西已經在腳本端處理了

**補充:**特殊字元正在更改為�(替換字元)

此問題與 SQL Server 排序規則無關。問題在連接到 SQL Server 之前發生(即字元被轉換)。如果問題可以通過在字元串前面加上大寫的“N”來解決,那麼腳本將無法在 SSMS 中正常工作(正如 OP 所說的那樣)。

這裡的問題與未知文件的編碼有關Invoke-Sqlcmd,因此構成文件的字節被錯誤地解釋。這就是為什麼它在粘貼到 SSMS 時可以正常工作的原因(因為該視窗的編碼是 UTF-16LE,就像所有 .NET / Windows 一樣,並且是 SSMS 已知的)。

我檢查了文件,似乎沒有像使用SQLCMD. 我假設文件被保存為 UTF-16LE(微軟領域的“Unicode”)或 UTF-8,但在任何一種情況下,都沒有字節順序標記 (BOM)。我建議使用包含字節順序標記的編碼重新保存文件(在 SSMS 等某些程序中“使用編碼保存”)。請務必選擇指定“BOM”或“帶簽名”的編碼(如在 MS 產品中)。BOM 是 2 - 4 個字元(取決於所使用的編碼),位於文件開頭,指示所使用的編碼(即 UTF-8、UTF-16LE、UTF-16BE、UTF-32LE 或 UTF-32BE) . BOM 是僅 Unicode 的功能,不存在用於非 Unicode 編碼。在文件中設置它後,任何打開文件的程序都會檢測到它並知道編碼是什麼,而無需您指定。希望這適用於Invoke-Sqlcmd.

如果您在 SQL 腳本 (C:\DailyPatch\run.sql) 中使用字元串,那麼我會確保您在單引號字元串之前放置一個 N。

用這個:

select * from table where column = N'value ô'

代替:

select * from table where column = 'value ô'

如果列是 nvarchar 或 nchar,則應保留 Unicode 值。

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