背景:我正在SQL Server中编写存储过程以产生一些数据的导出。这些文件需要采用XML格式,所以我在查询中使用for xml
进行了BCP处理。Unicode XML和Powershell转换为UTF-8的SQL Server BCP会产生奇怪的返回字符
字符串数据varchar
(不nvarchar
),但一些字符没有正确地转换,所以我们改变了BCP语句中使用-w
,而不是-CACP
。我们的最终用户不愿意使用文件大小,而是要求UTF-8,而我们希望放入XML指令语句,以便文件更“正确”的XML;一点Powershell似乎照顾两者。
一般来说,这个过程正在做我们想做的事情,但是里面含有CR/LF的数据存在一些奇怪现象 - 即,看起来BCP将CR转换为字符串“$#x0D;”,但是将LF保留为0x0A(当然,Unicode等同于0x00字节)。然后,Powershell语句似乎将“$#x0D;”作为更多的文本数据,它将(Unicode)0x0A变成(UTF-8)空间。这不是我们想要的!有趣的是,如果我离开XML指令部分,(Unicode)0x0A会被转换回(UTF-8)CR/LF,但会留下“$#x0D;”在数据中也是如此。
我提供了一个简化的例子,说明我们在下面做什么;将MyDatabase
更改为正常工作的数据库,并将C:\
路径更改为任何可行的工作,并且可以看到生成的文件 - 我使用TextPad以可视方式查看它们,并使用HexEdit检查实际的逐字节输出结果。有没有人看到任何明显的可能帮助?我一直在谷歌上搜索了一下,但似乎无法找到与我们的具体情况什么...
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周期? : - / –