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) 的隐式转换

不允许从数据类型 nvarchar 到 varbinary(max) 的隐式转换

使用Angularjs中的Web API将pdf文件作为varbinary(max)插入数据库?