将整数转换为十六进制,将十六进制转换为整数

因此,我在 Sybase 中使用了这个查询(其中 signal_data是一个列) ,但它在 Microsoft SQL Server 中不起作用:

HEXTOINT(SUBSTRING((INTTOHEX(signal_data)),5,2)) as Signal

我在 Excel 中也有它(其中 A1包含该值) :

=HEX2DEC(LEFT(DEC2HEX(A1),LEN(DEC2HEX(A1))-2))

有人知道我在 SQLServer 中是如何做到这一点的吗?

294744 次浏览

将 INT 转换为十六进制:

SELECT CONVERT(VARBINARY(8), 16777215)

将十六进制转换为 INT:

SELECT CONVERT(INT, 0xFFFFFF)

更新2015-03-16

上面的示例有一个限制,即它只在 HEX 值作为整数字面值给定时起作用。为了完整起见,如果要转换的值是十六进制字符串(如在 varchar 列中找到的) ,请使用:

-- If the '0x' marker is present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '0x1FFFFF', 1))


-- If the '0x' marker is NOT present:
SELECT CONVERT(INT, CONVERT(VARBINARY, '1FFFFF', 2))

注意: 字符串必须包含偶数个十六进制数字。奇数个数字将产生错误。

更多细节可以在 CAST 和 CONVERT (Transact-SQL)的“二进制样式”部分找到。我认为需要 SQLServer2008或更高版本。

使用 master.dbo.fnbintohexstr(16777215)转换为 varchar表示形式。

下面是 SQL 服务器的函数,它将整数值转换为十六进制的 varchar 表示形式。应该很容易适应其他数据库类型

例如:

SELECT dbo.ToHex(4095) --> FFF

SQL:

CREATE FUNCTION ToHex(@value int)
RETURNS varchar(50)
AS
BEGIN
DECLARE @seq char(16)
DECLARE @result varchar(50)
DECLARE @digit char(1)
SET @seq = '0123456789ABCDEF'


SET @result = SUBSTRING(@seq, (@value%16)+1, 1)


WHILE @value > 0
BEGIN
SET @digit = SUBSTRING(@seq, ((@value/16)%16)+1, 1)


SET @value = @value/16
IF @value <> 0 SET @result = @digit + @result
END


RETURN @result
END
GO

给出:

declare @hexStr varchar(16), @intVal int

返回文章页面 IntToHexStr:

select @hexStr = convert(varbinary, @intVal, 1)

HexStrToInt:

declare
@query varchar(100),
@parameters varchar(50)


select
@query = 'select @result = convert(int,' + @hb + ')',
@parameters = '@result int output'


exec master.dbo.Sp_executesql @query, @parameters, @intVal output

实际上,内置的函数名为 master.dbo.fn _ varbintohexstr。

例如:

SELECT 100, master.dbo.fn_varbintohexstr(100)

给你

1000x00000064

传统的4位十六进制非常直接。 从十六进制字符串到整数(假设值存储在名为 FHexString 的字段中) :

CONVERT(BIGINT,CONVERT(varbinary(4),
(SELECT master.dbo.fn_cdc_hexstrtobin(


LEFT(FMEID_ESN,8)
))
))

整数到十六进制字符串(假设值存储在名为 FInteger 的字段中) :

(SELECT master.dbo.fn_varbintohexstr(CONVERT(varbinary,CONVERT(int,
FInteger
))))

需要注意的是,当您开始使用导致寄存器共享的位大小时,尤其是在 Intel 机器上,由于 Intel 的小端点特性,寄存器中的 High 和 Low 以及 Left 和 Rights 将被交换。例如,当使用 varinary (3)时,我们讨论的是一个6个字符的十六进制。在这种情况下,您的位配对为从右到左的下列索引“54,32,10”。在一个情报系统中,你会期望“76,54,32,10”。因为你只使用8个中的6个,你需要记住自己做掉期。“76,54”代表你的左边“32,10”代表你的右边。逗号分开你的高和低。情报交换高和低,然后左和右。所以要做一个转换... 唉,你必须自己交换它们,例如,下面的转换是8个字符十六进制中的前6个:

(SELECT master.dbo.fn_replvarbintoint(
CONVERT(varbinary(3),(SELECT master.dbo.fn_cdc_hexstrtobin(
--intel processors, registers are switched, so reverse them




----second half
RIGHT(FHex8,2)+ --0,1 (0 indexed)
LEFT(RIGHT(FHex8,4),2)+ -- 2,3 (oindex)
--first half
LEFT(RIGHT(FHex8,6),2) --4,5


)))
))

这有点复杂,所以我会尽量保持我的转换为8个字符的十六进制(varbiny4)。

总之,这应该能够全面地回答你的问题。

Declare @Dato xml
Set @Dato = Convert(xml, '<dato>FF</dato>')
Select Cast( rw.value( 'xs:hexBinary( text()[1])' , 'varbinary(max)' ) as int ) From @Dato.nodes('dato') as T(rw)

SQLServer 相当于 Excel 的基于字符串的 DEC2HEX、 HEX2DEC 函数:

--Convert INT to hex string:
PRINT CONVERT(VARCHAR(8),CONVERT(VARBINARY(4), 16777215),2) --DEC2HEX


--Convert hex string to INT:
PRINT CONVERT(INT,CONVERT(VARBINARY(4),'00FFFFFF',2)) --HEX2DEC
IIF(Fields!HIGHLIGHT_COLOUR.Value="","#FFFFFF","#" & hex(Fields!HIGHLIGHT_COLOUR.Value) & StrDup(6-LEN(hex(Fields!HIGHLIGHT_COLOUR.Value)),"0"))

在字体颜色方面对我很有效

Maksym Kozlenko 给出的答案很不错,可以稍作修改以处理将数值编码为任何代码格式的问题。例如:

CREATE FUNCTION [dbo].[IntToAlpha](@Value int)
RETURNS varchar(30)
AS
BEGIN
DECLARE @CodeChars varchar(100)
SET @CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
DECLARE @CodeLength int = 26
DECLARE @Result varchar(30) = ''
DECLARE @Digit char(1)


SET @Result = SUBSTRING(@CodeChars, (@Value % @CodeLength) + 1, 1)
WHILE @Value > 0
BEGIN
SET @Digit = SUBSTRING(@CodeChars, ((@Value / @CodeLength) % @CodeLength) + 1, 1)
SET @Value = @Value / @CodeLength
IF @Value <> 0 SET @Result = @Digit + @Result
END


RETURN @Result
END

因此,像1.5亿这样的大数字只能变成6个字符(150,000,000 = “ MQGJMU”)

您还可以使用不同序列中的不同字符作为加密设备。或者传入代码字符和字符长度,并用作加密的 Salting 方法。

反过来说:

CREATE FUNCTION [dbo].[AlphaToInt](@Value varchar(7))
RETURNS int
AS
BEGIN
DECLARE @CodeChars varchar(100)
SET @CodeChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
DECLARE @CodeLength int = 26
DECLARE @Digit char(1)
DECLARE @Result int = 0
DECLARE @DigitValue int
DECLARE @Index int = 0
DECLARE @Reverse varchar(7)
SET @Reverse = REVERSE(@Value)


WHILE @Index < LEN(@Value)
BEGIN
SET @Digit = SUBSTRING(@Reverse, @Index + 1, 1)
SET @DigitValue = (CHARINDEX(@Digit, @CodeChars) - 1) * POWER(@CodeLength, @Index)
SET @Result = @Result + @DigitValue
SET @Index = @Index + 1
END
RETURN @Result

转换为十六进制:

SELECT FORMAT(512+255,'X')

要将十六进制字符串转换为 INT,我过去曾使用过这种方法。实际上,它可以被修改为将任何基数转换为 INT (八进制,二进制,等等)

Declare @Str varchar(200)
Set @str = 'F000BE1A'


Declare @ndx int
Set @ndx = Len(@str)
Declare @RunningTotal  BigInt
Set @RunningTotal = 0


While @ndx > 0
Begin
Declare @Exponent BigInt
Set @Exponent = Len(@Str) - @ndx


Set @RunningTotal = @RunningTotal +


Power(16 * 1.0, @Exponent) *
Case Substring(@str, @ndx, 1)
When '0' then 0
When '1' then 1
When '2' then 2
When '3' then 3
When '4' then 4
When '5' then 5
When '6' then 6
When '7' then 7
When '8' then 8
When '9' then 9
When 'A' then 10
When 'B' then 11
When 'C' then 12
When 'D' then 13
When 'E' then 14
When 'F' then 15
End
Set @ndx = @ndx - 1
End


Print @RunningTotal

下面是两个函数: dbo. HexToInt 和 dbo. IntToHex,我将它们用于这种转换:

if OBJECT_ID('dbo.HexToInt') is not null
drop function dbo.HexToInt
GO
create function dbo.HexToInt (@chars varchar(max))
returns int
begin
declare @char varchar(1), @len int, @i int, @r int, @tmp int, @pow int
set @chars = RTRIM(LTRIM(@chars))
set @len = LEN(@chars)
set @i = 1
set @r = 0
while @i <= @len
begin
set @pow = @len - @i
set @char = SUBSTRING(@chars, @i, 1)
if @char = '0'
set @tmp = 0
else if @char = '1'
set @tmp = 1
else if @char = '2'
set @tmp = 2
else if @char = '3'
set @tmp = 3
else if @char = '4'
set @tmp = 4
else if @char = '5'
set @tmp = 5
else if @char = '6'
set @tmp = 6
else if @char = '7'
set @tmp = 7
else if @char = '8'
set @tmp = 8
else if @char = '9'
set @tmp = 9
else if @char = 'A'
set @tmp = 10
else if @char = 'B'
set @tmp = 11
else if @char = 'C'
set @tmp = 12
else if @char = 'D'
set @tmp = 13
else if @char = 'E'
set @tmp = 14
else if @char = 'F'
set @tmp = 15
set @r = @r + @tmp * POWER(16,@pow)
set @i = @i + 1
end
return @r
end

第二个:

if OBJECT_ID('dbo.IntToHex') is not null
drop function dbo.IntToHex
GO
create function dbo.IntToHex (@val int)
returns varchar(max)
begin
declare @r varchar(max), @tmp int, @v1 int, @v2 int, @char varchar(1)
set @tmp = @val
set @r = ''
while 1=1
begin
set @v1 = @tmp / 16
set @v2 = @tmp % 16
if @v2 = 0
set @char = '0'
else if @v2 = 1
set @char = '1'
else if @v2 = 2
set @char = '2'
else if @v2 = 3
set @char = '3'
else if @v2 = 4
set @char = '4'
else if @v2 = 5
set @char = '5'
else if @v2 = 6
set @char = '6'
else if @v2 = 7
set @char = '7'
else if @v2 = 8
set @char = '8'
else if @v2 = 9
set @char = '9'
else if @v2 = 10
set @char = 'A'
else if @v2 = 11
set @char = 'B'
else if @v2 = 12
set @char = 'C'
else if @v2 = 13
set @char = 'D'
else if @v2 = 14
set @char = 'E'
else if @v2 = 15
set @char = 'F'
set @tmp = @v1
set @r = @char + @r
if @tmp = 0
break
end
return @r
end

可以使用 SQLServer2012及以上版本中提供的 FORMAT 函数

select FORMAT(10,'x2')

结果:

0a

Maksym Kozlenko 有一个很好的解决方案,其他人接近于 释放它的全部潜能,但是完全忽略了你可以定义任何字符序列,而 使用作为基准的长度。这就是为什么我喜欢这个稍微修改过的版本,因为它可以适用于基数16,或基数17,等等。

例如,如果你想要字母和数字,但不想 I 看起来像1,O 看起来像0。你可以这样定义任何序列。下面是一个“基数36”的形式,它跳过 I 和 O 来创建一个“修改后的基数34”。取消注释十六进制行,而是以十六进制运行。

declare @value int = 1234567890


DECLARE @seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE @seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE @result varchar(50)
DECLARE @digit char(1)
DECLARE @baseSize int = len(@seq)
DECLARE @workingValue int = @value


SET @result = SUBSTRING(@seq, (@workingValue%@baseSize)+1, 1)


WHILE @workingValue > 0
BEGIN
SET @digit = SUBSTRING(@seq, ((@workingValue/@baseSize)%@baseSize)+1, 1)


SET @workingValue = @workingValue/@baseSize
IF @workingValue <> 0 SET @result = @digit + @result
END


select @value as Value, @baseSize as BaseSize, @result as Result

值,基大小,结果

123456789034 T5URAA

我还将值移动到工作值,然后从工作值副本开始工作,作为个人首选项。

下面是附加的 逆转转变,对于任何序列,与基地定义为序列的长度。

declare @value varchar(50) = 'T5URAA'


DECLARE @seq varchar(100) = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ' -- modified base 34
--DECLARE @seq varchar(100) = '0123456789ABCDEF' -- hex
DECLARE @result int = 0
DECLARE @digit char(1)
DECLARE @baseSize int = len(@seq)
DECLARE @workingValue varchar(50) = @value


DECLARE @PositionMultiplier int = 1
DECLARE @digitPositionInSequence int = 0


WHILE len(@workingValue) > 0
BEGIN
SET @digit = right(@workingValue,1)
SET @digitPositionInSequence = CHARINDEX(@digit,@seq)
SET @result = @result + ( (@digitPositionInSequence -1) * @PositionMultiplier)


--select @digit, @digitPositionInSequence, @PositionMultiplier, @result


SET @workingValue = left(@workingValue,len(@workingValue)-1)
SET @PositionMultiplier = @PositionMultiplier * @baseSize
END


select @value as Value, @baseSize as BaseSize, @result as Result