背景:データの一部をエクスポートするためにSQL Serverにストアドプロシージャを作成しています。ファイルはXML形式である必要がありますので、質問にfor xml
とBCPingしています。Unicode XMLとPowershellのBCPから返される文字が奇妙なUTF-8に変換される
Stringデータvarchar
(ないnvarchar
)であるが、いくつかの文字が正しく変換されませんでしたので、私たちは-w
代わりの-CACP
を使用するためにBCP文を変更しました。私たちのエンドユーザは、UTF-8を要求するファイルサイズを嫌っていました。ファイルがより正確なXMLになるように、XMLディレクティブ文を入れたいと思っていました。少しPowershellは両方の世話をするように見えました。
一般的に言うと、プロセスは私たちが望んでいることを実行していますが、内部にCR/LFを含むデータには奇妙なものがあります。つまり、BCPはCRを文字列 "$#x0D; LFを0x0Aのままにしています(まあ、Unicodeに相当し、0x00バイトもあります)。 Powershellステートメントは、 "$#x0D;"を処理するように見えます。 (Unicode)0x0Aを(UTF-8)空間に変換します。これは私たちが望むものではありません!興味深いのは、(Unicode)0x0Aが(UTF-8)CR/LFに変換されて戻ってきても、XMLディレクティブの部分を残しておけば、 "$#x0D;データにも
ここでは、私たちが行っている作業の簡略化した例を示しました。 MyDatabase
を作業用のDBに変更して、C:\
のパスを変更すると、結果のファイルが表示されます。視覚的に見るためにTextPadを使用しています。実際のバイト単位の出力を調べるにはHexEditを使用します。誰も助けてくれる明白な何かを見ますか?私はなぜFORのXML/BCPは、だけでなく、LFをコードしないことを確認していない...
create table MyDatabase.dbo.TestTable (
StringData varchar (1000)
)
insert into MyDatabase.dbo.TestTable (StringData)
select
'I have return characters in me.' + char (13) + char (10) + 'Will the file I''m output to be okay?'
declare @Query varchar (2000)
declare @Command varchar (2000)
set @Query = 'select * '
+ 'from MyDatabase.dbo.TestTable with (nolock) '
+ 'for xml path (''StringData''), root (''TableData''), elements, type'
set @Command = 'bcp "' + @Query + '" queryout C:\TestXMLUnicodeData_1.xml -w -T -S' + cast(@@ServerName as varchar)
exec master.dbo.xp_cmdshell @Command
set @Command = 'powershell "Get-Content C:\TestXMLUnicodeData_1.xml | Set-Content -Encoding UTF8 C:\TestXMLUTF8Data_1.xml'
exec master.dbo.xp_cmdshell @Command
set @Query = 'select * '
+ 'from MyDatabase.dbo.TestTable with (nolock) '
+ 'for xml path (''StringData''), root (''TableData''), elements, type'
set @Command = 'bcp "' + @Query + '" queryout C:\TestXMLUnicodeData_2.xml -w -T -S' + cast(@@ServerName as varchar)
exec master.dbo.xp_cmdshell @Command
set @Command = 'powershell "''<?xml version=\"1.0\" encoding=\"UTF-8\"?>'' + (Get-Content C:\TestXMLUnicodeData_2.xml)'
+ ' | Set-Content -Encoding UTF8 C:\TestXMLUTF8Data_2.xml'
exec master.dbo.xp_cmdshell @Command
ありがとうございました。残念ながら、私はそれが最も問題を引き起こしている最初のことだと思います。私は、プロセスの始めにCRとLFの両方を明示的にエンコードし、Powershellを使用してエンコードされた文字列をエンディングのCR/LFに戻す作業をさらに進めました。結局のところ、CPUサイクルはいくらですか? : - / –