VarBinary(max) 到整数列表
Posted
技术标签:
【中文标题】VarBinary(max) 到整数列表【英文标题】:VarBinary(max) to list of integers 【发布时间】:2022-01-03 18:54:12 【问题描述】:对于我的应用程序,我将一些值转储到 varbinary(max) 列中。 现在我正在尝试再次从那里获取数据,并希望从 sql 中获取包含所有值的列表。
在我的 C# 应用程序中,我执行以下任务:
Data = ints.SelectMany(BitConverter.GetBytes).ToArray();
然后将此数据插入到数据库中。
我正在寻找的是一个关于如何检索数据的 SQL 脚本,不仅仅是作为一个 blob,而是作为所有值的列表。 所以是这样的:
SELECT * FROM RawData CROSS APPLY CastToInt(SplitBinary(RawData.Data, 4)) WHERE RawDataId = 1;
有人知道实现这种功能的方法吗?
作为背景信息,我正在尝试在 Grafana 中创建 RawData 图表。
【问题讨论】:
【参考方案1】:拆分 32 位 int 值的一种方法是使用二进制字符串拆分函数。下面的 TVF 示例使用实用程序计数表来简化任务。
Tally 表 DDL:
DROP TABLE IF EXISTS dbo.Tally;
CREATE TABLE dbo.Tally(Number int NOT NULL);
--load 1 million numbers
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t1k AS (SELECT 0 AS n FROM t10 AS t10a CROSS JOIN t10 AS t10b CROSS JOIN t10 AS t10c)
,t1m AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS Number FROM t1k AS t1ka CROSS JOIN t1k AS t1kb)
INSERT INTO dbo.Tally WITH(TABLOCKX) (Number)
SELECT Number
FROM t1m;
--create primary key on number
ALTER TABLE dbo.Tally
ADD CONSTRAINT PK_Tally PRIMARY KEY (Number)
WITH(FILLFACTOR=100, MAXDOP = 1);
GO
二进制 int 拆分 TVF:
CREATE OR ALTER FUNCTION dbo.BINARY_INT_STRING_SPLIT(@ints varbinary(MAX))
RETURNS TABLE
AS
RETURN(
--reverse serialized bytes for little-endian order
SELECT CAST(SUBSTRING(@ints,Tally.Number*4,1) + SUBSTRING(@ints,Tally.Number*4-1,1) + SUBSTRING(@ints,Tally.Number*4-2,1) + SUBSTRING(@ints,Tally.Number*4-3,1) AS int) AS int
FROM dbo.Tally
WHERE Tally.Number <= DATALENGTH(@ints)/4
);
GO
示例用法:
CREATE TABLE dbo.RawData(RawDataId int, Data varbinary(MAX));
INSERT INTO dbo.RawData(RawDataId, Data) VALUES(1, 0x01000000);
INSERT INTO dbo.RawData(RawDataId, Data) VALUES(2, 0x02000000);
INSERT INTO dbo.RawData(RawDataId, Data) VALUES(3, 0xffffffff);
GO
SELECT RawDataId, ints.int
FROM dbo.RawData
CROSS APPLY dbo.BINARY_INT_STRING_SPLIT(RawData.Data) AS ints;
GO
【讨论】:
这看起来很有希望!这是否也可以重写以使用实数? @Foitn,T-SQL 不允许从 varbinary 转换为 real/float。即使是这样,不同的 .NET 单一数据类型和 SQL Server 浮点数据类型结构和字节序也可能会带来额外的复杂性。恕我直言,SQLCLR 函数将更适合实际转换。以上是关于VarBinary(max) 到整数列表的主要内容,如果未能解决你的问题,请参考以下文章
将文件作为 varbinary(max) 保存到 SQL 的问题
C#/SQL:从 DataGridView 到 Picturebox 的 Varbinary(max) 列
在实体框架中将对象类型属性映射到 varbinary(MAX)
不允许从数据类型 nvarchar 到 varbinary(max) 的隐式转换