Sql 是否可以将xml作为字符串插入到varbinary中,并且它将类似于作为blob插入?

Sql 是否可以将xml作为字符串插入到varbinary中,并且它将类似于作为blob插入?,sql,sql-server,xml,Sql,Sql Server,Xml,是否可以将xml作为字符串插入到varbinary中,并且它将类似于作为blob插入?例如,当我将xml作为blob插入时 declare @i int = 1 declare @file varchar(2000) = concat('K:\test\file',@i,'.xml'); declare @blob varbinary(max) declare @sql nvarchar(max) = concat(N'select @blob = BulkColumn FROM OPENRO

是否可以将xml作为字符串插入到varbinary中,并且它将类似于作为blob插入?例如,当我将xml作为blob插入时

declare @i int = 1
declare @file varchar(2000) = concat('K:\test\file',@i,'.xml');
declare @blob varbinary(max)
declare @sql nvarchar(max) = concat(N'select @blob = BulkColumn FROM 
OPENROWSET(BULK ''',@file,''', SINGLE_BLOB) myfile')

exec sp_executesql @sql, N'@blob varbinary(max) output', @blob = @blob 
output
select @blob 

insert tab1 values (@blob)
以blob形式插入的文件如下所示

当我插入相同的xml但作为字符串时

INSERT INTO tab1 VALUES ( Convert (varbinary(MAX), N'
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Dont forget me this weekend!</body>
</note>'  ))
插入到tab1值中(Convert(varbinary(MAX),N'
托弗
贾尼
提醒
这个周末别忘了我!
'  ))
它看起来完全不同

@雅各布

@锡亚尔


像从磁盘读取文件一样,将文件存储为
VARBINARY
是一个非常糟糕的想法

一些背景

DECLARE @YourThirdVarbinary VARBINARY(MAX)=0xfffe3c006e006f00740065003e003c0074006f003e00;
SELECT CAST(@YourThirdVarbinary AS NVARCHAR(MAX));
前导的
FFFE
指向一个带有

下面的3C00 6E00 6F00。。。清楚地显示您正在读取2字节编码字符

SQL Server在内部使用
UCS-2
,无法读取每个
UTF-16
编码。我假设,你生活在一个国家,在那里你要处理许多字符,这些字符不是简单的拉丁语

但您提供的第一个示例是单字节编码字符串:

DECLARE @YourFirstVarbinary VARBINARY(MAX)=0x3c6e6f74653E0D0A3c746f3e546f76653c2f746f3e;
SELECT CAST(@YourFirstVarbinary AS VARCHAR(MAX));
代码点之间缺少的
00
清楚地表明,这是没有BOM的1字节存储,可能是某种
UTF-8

UTF-8
用一个字节存储纯拉丁语,但特殊字符将占用更多字节,一个字母最多4个字节

SQL Server将1字节编码字符串视为
VARCHAR
,它是扩展的ascii,依赖于
排序规则(包括
代码页
)(多字节代码必须导致错误!)

您将发现构成单词
的相同代码点:

DECLARE @PureCodePoints VARBINARY(MAX)=0x3c6e6f74653E;
SELECT CAST(@PureCodePoints AS VARCHAR(MAX));
并作为2字节代码(参见
N
VARCHAR):

明确建议
  • 将XML存储在本机类型的列中!优点:XML不是作为您看到的文本存储的,而是作为层次结构树存储的。这要快得多!使用这种方法,您必须将
    VARBINARY
    转换为字符串,并一遍又一遍地解析它

  • 如果无法确保在任何情况下都知道编码,并且SQL Server能够处理此格式,则切勿将数据存储为
    VARBINARY


存储XML的方式取决于如何处理这些数据

  • 如果您的目标只是存储和访问该文件,而不管它是否确实是XML,或者是绝对正确的
  • 如果您知道它是一个文本文件(包括XML),但不需要对其进行任何特定于XML的操作,则可以使用or
  • 如果您要进行任何类型的XML操作,这将是一个合乎逻辑的选择
根据我的经验,后者有一些警告:

  • XML可能会被签名,如果您应该小心不要破坏它的话。在这种情况下,您应该考虑将XML存储为二进制,但添加一个额外的XML列。

  • 如果XML指定的编码与应用程序提供的编码不兼容,则可能会出现以下错误:

    XML解析:第1行,字符45,无法切换编码

    以下示例说明了此场景:

选择强制转换(N''为xml)
选择强制转换(N“”为xml)
选择强制转换(“”作为xml)
虽然这些都很好:

选择强制转换(N''为xml)
选择强制转换(“”作为xml)
选择强制转换(“”作为xml)
选择强制转换(N“”为xml)
选择强制转换(“”作为xml)

为什么不直接使用xml数据类型?没有回答你的问题,为什么你的blob看起来与varbinary数据不同。你的文件的开头是否也有换行符,在
?@Jacob之前,必须使用varbinary数据类型,但我尝试过将其另存为xml,然后将其转换为varbinary,但输出与我前面提到的2不同。@Siyual删除换行符也没有帮助。
DECLARE @PureCodePointsWide VARBINARY(MAX)=0x3c006e006f00740065003E00;
SELECT CAST(@PureCodePointsWide AS NVARCHAR(MAX));