我有以下TSQL:
SELECT
Id,
CAST('' as XML).value('xs:base64Binary(sql:column("Content"))', 'NVARCHAR(MAX)') + '=' as Content,
Name
FROM Files
ORDER BY Id
在“内容”列的末尾未添加字符“ =”。我也尝试过:
SELECT
Id,
CONCAT(CAST('' as XML).value('xs:base64Binary(sql:column("Content"))', 'NVARCHAR(MAX)'), '=') as Content,
Name
FROM Files
ORDER BY Id
相同的问题...字符串末尾未添加字符'='。
我想念什么?
答案 0 :(得分:2)
在列的末尾没有添加字符'='
可以。 SSMS可能会截断该值。但是,您不应该首先在末尾添加“ =”。这是base64规范的一部分,并且xml.value()将添加'='或'=='以根据需要填充该值。在末尾添加“ =”将产生无效的base64字符串,例如:
use tempdb
go
drop table if exists Files
go
create table Files(id int primary key, name varchar(200), Content varbinary(max))
go
insert into Files(id,name,Content) values (1,'1',0x9789798d7987907a09797a987908790787897b0987d9087097e09879087d907907097097a0c0909890809789798798789798707097090)
SELECT
Id,
CAST('' as XML).value('xs:base64Binary(sql:column("Content"))', 'NVARCHAR(MAX)') + '=' as Content,
Name
FROM Files
ORDER BY Id
/*
CXiXmNeYeQegl5eph5CHkHh4l7CYfZCHCX4Jh5CH2QeQcJcJegwJCYkICXiXmHmHiXmHBwlwkA===
*/
以下是比较.NET和SQL Server的base64编码的示例:
using System;
using System.Data;
using System.Linq;
using System.Data.SqlClient;
namespace netcore3test
{
class File
{
public byte[] Content { get; set; }
}
class Program
{
static void Main(string[] args)
{
var maxLen = 1024 * 1024;
using var con = new SqlConnection("server=localhost;database=tempdb;integrated security=true");
con.Open();
var cmd = con.CreateCommand();
cmd.CommandText = @"
with q as (select @buf Content)
select CAST('' as XML).value('xs:base64Binary(sql:column(""Content""))', 'NVARCHAR(MAX)') base64string
from q
";
var pBuf = cmd.Parameters.Add("@buf", SqlDbType.VarBinary, -1);
var rand = new Random(0);
;
for (int len = 0; len < maxLen; len++)
{
var buf = new byte[len];
rand.NextBytes(buf);
pBuf.Value = buf;
var netBase64 = Convert.ToBase64String(buf);
var sqlBase64 = (string)cmd.ExecuteScalar();
var json = @$"{{""Content"" : ""{sqlBase64}"" }}";
var File = System.Text.Json.JsonSerializer.Deserialize<File>(json);
var sqlBuf = File.Content;
if (!buf.SequenceEqual(sqlBuf) || netBase64 != sqlBase64)
{
Console.WriteLine($"Fail {netBase64} {sqlBase64}");
}
Console.WriteLine(sqlBase64);
}
}
}
}