感谢这是一篇旧文章,但对于那些希望在 T-SQL 中执行此操作的人(我曾经是),以下内容可能很有用。
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ifn_HexReal48ToFloat]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
drop function [dbo].[ifn_HexReal48ToFloat]
go
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create function [dbo].[ifn_HexReal48ToFloat]
(
@strRawHexBinary char(12), -- NOTE. Do not include the leading 0x
@bitReverseBytes bit
)
RETURNS FLOAT
AS
BEGIN
-- Reverse bytes if required
-- e.g. 3FF4 0000 0000 is stored as
-- 0000 0000 F43F
declare @strNewValue varchar(12)
if @bitReverseBytes = 1
begin
set @strNewValue=''
declare @intCounter int
set @intCounter = 6
while @intCounter>=0
begin
set @strNewValue = @strNewValue + substring(@strRawHexBinary, (@intCounter * 2) + 1,2)
set @intCounter = @intCounter - 1
end
end
-- Convert the raw string into a binary
declare @binBinaryFloat binary(6)
set @binBinaryFloat = convert(binary(6),'0x' + isnull(@strNewValue, @strRawHexBinary),1)
-- Based on original hex to float conversion at http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=81849
-- and storage format documented at
-- http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/internaldataformats_xml.html
-- Where, counting from the left
-- Sign = bit 1
-- Exponent = bits 41 - 48 with a bias of 129
-- Fraction = bits 2 - 40
return
SIGN
(
CAST(@binBinaryFloat AS BIGINT)
)
*
-- Fraction part. 39 bits. From left 2 - 40.
(
1.0 +
(CAST(@binBinaryFloat AS BIGINT) & 0x7FFFFFFFFF00) * POWER(CAST(2 AS FLOAT), -47)
)
*
-- Exponent part. 8 bits. From left bits 41 -48
POWER
(
CAST(2 AS FLOAT),
(
CAST(@binBinaryFloat AS BIGINT) & 0xff
- 129
)
)
end
确认
0.125 是 0x 0000 0000 007E(或 0x 7E00 0000 0000 反转)
select dbo.ifn_HexReal48ToFloat('00000000007E', 0)
select dbo.ifn_HexReal48ToFloat('7E0000000000', 1)
输入是 char12,因为我必须从其他 2 个较大的二进制字段的中间提取二进制文件并将它们分流在一起,因此已经将其作为 char12。如果不需要事先进行任何操作,很容易更改为二进制(6)输入。
顺便说一句,在我正在实施的场景中,T-SQL 变体的性能优于 C# CLR 代码,因此上面的 C# 代码可能更好。虽然不是所有地方都允许 CLR 代码进入 SQL Server,但如果可以的话,也许你应该这样做。有关更多背景知识,http://www.simple-talk.com/sql/t-sql-programming/clr-performance-testing/ 上的文章做了一些深度测量,显示了 T-SQL 和 CLR 之间的一些显着差异。