是否可以将xml作为字符串插入到varbinary中,并且它类似于作为blob插入?例如,当我将xml作为blob插入时
import org.springframework.web.portlet.ModelAndView;
当我插入相同的xml但作为字符串
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)
看起来完全不同
@Jacob
@Siyual
答案 0 :(得分:0)
将文件存储为VARBINARY
是一个非常糟糕的主意,就像从磁盘中读取文件一样。
一些背景
DECLARE @YourThirdVarbinary VARBINARY(MAX)=0xfffe3c006e006f00740065003e003c0074006f003e00;
SELECT CAST(@YourThirdVarbinary AS NVARCHAR(MAX));
前导FFFE
指向带有byte order mark的 UTF-16小端编码文件。
以下3C00 6E00 6F00 ...清楚地表明您正在阅读 2字节编码的字符。
SQL-Server在内部使用UCS-2
,并且本身无法读取每个UTF-16
编码。我假设你生活在一个国家,在那里你处理许多角色,而不是普通的拉丁语 ......
但您提供的第一个示例是单字节编码的字符串:
DECLARE @YourFirstVarbinary VARBINARY(MAX)=0x3c6e6f74653E0D0A3c746f3e546f76653c2f746f3e;
SELECT CAST(@YourFirstVarbinary AS VARCHAR(MAX));
您的代码点之间缺少00
显示,这是 1字节存储没有BOM,可能是某种UTF-8
!
UTF-8
将普通拉丁语存储为单个字节,但特殊字符将占用更多字节,一个字母最多可包含4个字节。
SQL-Server会将 1字节编码的字符串视为VARCHAR
,扩展为ascii ,依赖于COLLATION
(包括a code page
)(多字节代码必定会导致错误!)
您会发现形成单词<note>
的相同代码点:
DECLARE @PureCodePoints VARBINARY(MAX)=0x3c6e6f74653E;
SELECT CAST(@PureCodePoints AS VARCHAR(MAX));
作为 2字节代码(参见N
VARCHAR):
DECLARE @PureCodePointsWide VARBINARY(MAX)=0x3c006e006f00740065003E00;
SELECT CAST(@PureCodePointsWide AS NVARCHAR(MAX));
将XML存储在本机类型的列中!优点:XML不会存储为您看到的文本,而是存储为层次树。这快得多!使用您的方法,您必须将VARBINARY
强制转换为字符串并一遍又一遍地解析...
永远不要将数据存储为VARBINARY
,如果您无法确保,您知道任何情况下的编码,并且SQL-Server将能够处理此格式。
答案 1 :(得分:0)
存储XML的方式取决于对这些数据的处理方式。
根据我的经验,后者有一些警告:
可能对XML进行了签名,如果要注意不要破坏它。在这种情况下,您应该考虑将XML存储为二进制文件,但要添加一个额外的XML列。
如果您的XML指定的编码与应用程序提供的编码不兼容,则可能会出现诸如以下错误:
XML解析:第1行,字符45,无法切换编码
以下示例说明了这种情况:
SELECT CAST(N'<?xml version="1.0" encoding="windows-1251"?><xml></xml>' AS xml)
SELECT CAST(N'<?xml version="1.0" encoding="utf-8"?><xml></xml>' AS xml)
SELECT CAST('<?xml version="1.0" encoding="utf-16"?><xml></xml>' AS xml)
这些很好:
SELECT CAST(N'<?xml version="1.0" encoding="utf-16"?><xml></xml>' AS xml)
SELECT CAST('<?xml version="1.0" encoding="utf-8"?><xml></xml>' AS xml)
SELECT CAST('<?xml version="1.0" encoding="windows-1251"?><xml></xml>' AS xml)
SELECT CAST(N'<xml></xml>' AS xml)
SELECT CAST('<xml></xml>' AS xml)