【问题标题】:Convert integer to hex and hex to integer将整数转换为十六进制和十六进制转换为整数
【发布时间】:2010-10-16 17:23:25
【问题描述】:

所以我在 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))

有谁知道我将如何在 SQL Server 中执行此操作?

【问题讨论】:

    标签: sql sql-server integer hex


    【解决方案1】:

    将 INT 转换为十六进制:

    SELECT CONVERT(VARBINARY(8), 16777215)
    

    将十六进制转换为 INT:

    SELECT CONVERT(INT, 0xFFFFFF)
    

    2015-03-16 更新

    上面的例子有一个限制,它只在十六进制值作为整数文字给出时才有效。为了完整起见,如果要转换的值是十六进制字符串(例如在 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 and CONVERT (Transact-SQL)的“二进制样式”部分找到。我认为需要 SQL Server 2008 或更高版本。

    【讨论】:

    • 将其转换为 VARBINARY 将提供十六进制值的数据。不能对其进行字符串操作
    • @Bill Karwin,Pavan 是正确的。 Sql Server 2008 可以通过convert 函数执行此操作,但 2005 及以下版本不能。
    • 使用 8 字符十六进制时,例如使用 ARGB 转换为 BIGINT 而不是 INT。 INT 的最大值仅为 2,147,483,647 或 7FFFFFFF。使用 INT 时要注意,返回到 hex 的往返可以工作,但结果与 Excel 的 Hex2Dec 不同。
    • SELECT CONVERT(INT, CONVERT(varbinary, '01', 2)) 返回12337 (SQL Server 2005)
    • 第一个示例不转换为十六进制:它们转换为二进制。 (二进制值独立于任何数字基数存在:数字基数仅在字符串表示的上下文中才有意义。)(此外,参数不必是文字(尽管它必须是整数。))它们可能看起来像是在转换为十六进制,因为在将二进制转换为字符串(例如显示它)时,默认情况下它以十六进制表示。 (这可用于转换为十六进制,如@KipBryan 的回答所示,但 DenNukem 和 wndproc 的回答更简单。)
    【解决方案2】:

    其实内置函数名为master.dbo.fn_varbintohexstr。

    所以,例如:

    SELECT 100, master.dbo.fn_varbintohexstr(100)
    

    给你

    100 0x00000064

    【讨论】:

    【解决方案3】:

    SQL Server 等效于 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
    

    【讨论】:

      【解决方案4】:

      将整数转换为十六进制:

      SELECT FORMAT(512+255,'X')

      【讨论】:

      【解决方案5】:

      可以使用 SQL Server 2012 及以上版本提供的函数 FORMAT

      select FORMAT(10,'x2')
      

      结果:

      0a
      

      【讨论】:

        【解决方案6】:

        传统的 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
                        ))))
        

        需要注意的重要一点是,当您开始使用导致寄存器共享的位大小时,尤其是在英特尔机器上,由于英特尔的小端特性,您在寄存器中的高、低、左和右将被交换。例如,当使用 varbinary(3) 时,我们谈论的是 6 个字符的 Hex。在这种情况下,您的位从右到左配对为以下索引“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 个字符的十六进制 (varbinary(4))。

        总之,这应该可以回答您的问题。全面。

        【讨论】:

          【解决方案7】:

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

          例如:

          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
          

          【讨论】:

          • 它正在工作!完美的!您只需将“IF @ value 0”替换为“IF @ value 0”
          • 我喜欢这个解决方案,因为它可以轻松修改为更强大的解决方案。我提供了一个使用序列长度作为基础的示例解决方案。
          【解决方案8】:

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

          【讨论】:

          • select master.sys.fn_varbintohexstr(1) 2008 年
          【解决方案9】:
          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)
          

          【讨论】:

            【解决方案10】:

            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")

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

            反过来:

            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
            

            【讨论】:

              【解决方案11】:

              Maksym Kozlenko 有一个很好的解决方案,其他人接近 释放它的全部潜力,但随后完全错过了意识到您可以定义任何字符序列,并且 使用它的长度作为基础。这就是为什么我喜欢他的解决方案的这个稍微修改过的版本,因为它适用于 base 16 或 base 17 等。

              例如,如果您想要字母和数字,但不喜欢 I 看起来像 1 和 O 看起来像 0,该怎么办。您可以通过这种方式定义任何序列。下面是“Base 36”的一种形式,它跳过 I 和 O 以创建“修改的 base 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
              

              值、基数、结果

              1234567890, 34, 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
              

              【讨论】:

                【解决方案12】:

                鉴于:

                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
                

                【讨论】:

                  【解决方案13】:
                  IIF(Fields!HIGHLIGHT_COLOUR.Value="","#FFFFFF","#" & hex(Fields!HIGHLIGHT_COLOUR.Value) & StrDup(6-LEN(hex(Fields!HIGHLIGHT_COLOUR.Value)),"0"))
                  

                  作为字体颜色的表达对我有用

                  【讨论】:

                    【解决方案14】:

                    为了将十六进制字符串转换为 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
                    

                    【讨论】:

                      【解决方案15】:

                      下面是两个函数: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
                      

                      【讨论】:

                        猜你喜欢
                        • 2014-04-16
                        • 2016-12-04
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-08-11
                        • 2011-08-05
                        相关资源
                        最近更新 更多