【问题标题】:MSQL Query Get the Int value of a Hex value of an IntegerSQL Query 获取 Integer 的 Hex 值的 Int 值
【发布时间】:2012-02-05 21:26:25
【问题描述】:

背景

只是为了给您提供背景信息,我提供了一些背景知识,说明我为什么要这样做:

我有一个表“cp”,其中有一个 [id] 字段,它是每个注册的标识符相同的对象,最好它们都从 1 开始,因此我创建了一个名为 label 的 int 字段,而不是使用 id 字段,该字段将与帐户 ID 一起用于查找每个帐户的唯一记录。

 field       | type
 ________________________
  id         | int
  label      | int
  account_id | int

当注册在屏幕上打印出来时,我希望它们显示为 5 位十六进制数字,我可以在 c# 代码中简单地执行以下操作

 value.ToString("X")

但是,在我添加新标签字段之前,数据库中的现有条目存在我的问题。 我发现了几个类似的问题,但没有回答我的问题

问题

我有 ids (1,2,3,----,11,12,13,---etc) 值 1-9 的字段可以简单地复制为 value.ToString("X" ) 只会对这些值不做任何事情,但是如果我只是复制值 11 将返回“B”,它正确地是十六进制值 11 但是我希望它返回“11”,所以我需要一个 SQL 脚本来转换 11 => 17 (即 0x11 的十六进制值),以便应用程序读取它时会将值 11 输出到屏幕。

这只会发生一次以转换现有的 id,这就是为什么我希望 SQL 脚本在一批中完成所有操作,而不是将其构建到应用程序中。

我想要的是类似于下面的内容,因此它假定 in 的值是十六进制值并将其转换回 Int。

 SELECT CONVERT(INT, '0x' + id) FROM cp;

我可以通过执行以下操作在 C# 中获得正确的效果

 int.Parse(value.ToString(),System.Globalization.NumberStyles.HexNumber).ToString()

更新:我已经为我的用例找到了解决这个问题的方法,但有人提出了一些困惑,我将在数据库中进行所有转换,我假设上面的 SELECT 语句。澄清这是转换现有记录的一次性事件。请注意以下语句不起作用,但 stackoverflow 不允许我编辑原始语句,因为更改少于 15 个字符。

 UPDATE [dbname].[dbo].[cp] set [Label] = CONVERT(INT, '0x' + id); 

【问题讨论】:

    标签: c# sql sql-server


    【解决方案1】:

    您不应该在 SQL 中进行数字格式设置。让整数作为整数从数据库中出来,并在表示层中对其进行格式化。你完全没有提到那个表示层是什么,所以不可能多说,但是如果你这样做,当你的老板过来说有些用户想看十六进制,有些用户想看时,你就注定了以 10 为基数。

    【讨论】:

    • 表示层是c#,正如我认为会在问题中指出的那样,我没有在SQL中进行HEX转换,我只是想要一个转换器来处理现有记录,它使用 sql 查询来执行此操作似乎很有意义,然后业务层可以处理任何新记录。而不是将代码构建到业务层中仅用于一种用途。
    • 另外转换的原因是可以显示的字符数为 5,十进制限制为 100,000 条记录,现在发现对于我们的案例来说太低了,其中十六进制数字可以有 1,048,576 条记录。所以不会有客户需要查看 base-10 值的情况,不幸的是我不能使用 base-36 由于字符混淆 O=>0 和 l=>1 所以我被 HEX atm 卡住了但至少我现在已经给了客户 10 倍的可能记录数量,这在目前的规范范围内。
    【解决方案2】:

    找到了答案,它不是很漂亮,但它解决了我的问题,所以我想我会与你分享。如果有人有一个更简单的解决方案,那就太好了,但与此同时,我们走了。

    创建一个 MSQL 函数

    CREATE FUNCTION ConvertFromBase  
    (  
        @value AS VARCHAR(MAX),  
        @base AS BIGINT  
    ) RETURNS BIGINT AS BEGIN  
    
    -- just some variables  
    DECLARE @characters CHAR(36),  
            @result BIGINT,  
            @index SMALLINT;  
    
    -- initialize our charater set, our result, and the index  
    SELECT @characters = '0123456789abcdefghijklmnopqrstuvwxyz',  
           @result = 0,  
           @index = 0;  
    
    -- make sure we can make the base conversion.  there can't  
    -- be a base 1, but you could support greater than base 36  
    -- if you add characters to the @charater string  
    IF @base < 2 OR @base > 36 RETURN NULL;  
    
    -- while we have characters to convert, convert them and  
    -- prepend them to the result.  we start on the far right  
    -- and move to the left until we run out of digits.  the  
    -- conversion is the standard (base ^ index) * digit  
    WHILE @index < LEN(@value)  
        SELECT @result = @result + POWER(@base, @index) *   
                         (CHARINDEX  
                            (SUBSTRING(@value, LEN(@value) - @index, 1)  
                            , @characters) - 1  
                         ),  
               @index = @index + 1;  
    
    -- return the result  
    RETURN @result;  
    
    END  
    

    然后只需执行以下查询

     UPDATE [cp] SET label = dbo.ConvertFromBase(id,16);
    

    这个解决方案是在http://dpatrickcaldwell.blogspot.com/2009/05/converting-hexadecimal-or-binary-to.html发现的

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 2021-11-07
      • 2016-03-23
      • 2019-03-13
      • 2023-03-14
      • 2016-07-07
      • 2016-03-16
      相关资源
      最近更新 更多