通过系统定义的函数

时间:2017-04-11 08:33:20

标签: hex hana

我正致力于在SAP HANA中创建一个视图。

我有A栏,A的数据类型是NVARCHAR。

A中的值如下所示。我只需要使用最后5位数并将其转换为十进制数。

A  
000000000000000000000000000EF80A
000000000000000000000000000EF812
000000000000000000000000000EF80E
000000000000000000000000000EF809
000000000000000000000000000EF80B
000000000000000000000000000EF80C
000000000000000000000000000EF80D

我使用了函数

Select HEXTOBIN(0xEF80A) from dummy;

这给了我必要的结果。

但上述查询中的0x表示将数字(EF80A)标记为十六进制。

每当我必须动态获取5个最后一个数字时,我无法分配0x表示法。

我试过以下:
1)substr的最后5位数,并用0x连接...这不起作用,因为' 0x'被认为是字符串,而它只是表示法。

select distinct '0x' || right(A,5 )  from dummy;

有人可以帮助我如何用A列的最后5个字符给出0x来标记它是十六进制的吗?

在没有用户定义的功能的情况下,是否有可用于此转换的直接功能?

1 个答案:

答案 0 :(得分:0)

十六进制数字的0x...表示法和字符串的X'...'仅对类型文字有效。 例如。 0xEF80A显式地将文字键入以十六进制表示法给出的数字。在内部,数字当然会被处理,好像你会给出一个整数 为了能够将其应用于现有字符串,需要使用十六进制到数字转换功能,并且SAP HANA不会随附一个。

我在https://archive.sap.com/discussions/thread/3652555

发布了此类功能的示例实现

为了方便起见,请再次提及:

drop function hexstr2int;
CREATE FUNCTION hexstr2int (IN i_hex VARCHAR(2000)) 
RETURNS o_result BIGINT  
LANGUAGE SQLSCRIPT  
SQL SECURITY INVOKER
READS SQL DATA
AS
BEGIN
  DECLARE   pos INTEGER := 1;
  DECLARE   hex_len INTEGER;
  DECLARE   current_digit VARCHAR(1);
  DECLARE   current_val INTEGER;
  DECLARE   result BIGINT := 0;
    DECLARE   tmphex VARCHAR(2000);

    DECLARE hexstr2int CONDITION FOR SQL_ERROR_CODE 10001;
  DECLARE EXIT HANDLER FOR hexstr2int RESIGNAL;
    -- some sanitation
    tmphex := UPPER(:i_hex);
    hex_len := LENGTH(:tmphex);
   WHILE :pos <= :hex_len DO
        result := :result * 16;
        current_digit := SUBSTR(:tmphex, :pos, 1);
        -- format checking
       IF NOT ((:current_digit >= 'A' and :current_digit <= 'F') or
                  (:current_digit >= '0' and :current_digit <= '9')) THEN
           SIGNAL hexstr2int SET MESSAGE_TEXT = 
                 'Invalid hex cipher: ' || :current_digit || ' at position ' || :pos;
        END IF;
        current_val := MOD(to_number(to_binary(:current_digit)),30);
        IF :current_val >= 11 THEN
             result := :result + :current_val - 1;
        ELSE
             result := :result + :current_val;
        END IF;
        pos := :pos + 1;
   END WHILE;
  o_result := :result;
END;