拆分 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