Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/api/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正在查找任何OS/400 API封装在用户定义的SQL函数中的外部SQL存储过程中的工作示例_Sql_Api_Stored Procedures_Db2_Ibm Midrange - Fatal编程技术网

正在查找任何OS/400 API封装在用户定义的SQL函数中的外部SQL存储过程中的工作示例

正在查找任何OS/400 API封装在用户定义的SQL函数中的外部SQL存储过程中的工作示例,sql,api,stored-procedures,db2,ibm-midrange,Sql,Api,Stored Procedures,Db2,Ibm Midrange,目前有两个问题: 1) 下面的示例使用外部SQL存储过程包装OS/400 API,外部SQL存储过程是SQL用户定义表函数中的进一步包装,它编译和运行时都不会出错,但在传递作业名称(即当前作业)的“*”时,它会为作业信息返回空格和零。任何关于原因的提示都将不胜感激。注意:如果我传递了一个不存在的作业,那么QUSRJOBI api会正确地抛出一个错误,因此代码的行为部分正确。如果我传递了正确的活动工单名称、工单用户和工单编号,则不会发生错误,但仍会返回空格和零。我已经试过用CHAR(85)和VAR

目前有两个问题:

1) 下面的示例使用外部SQL存储过程包装OS/400 API,外部SQL存储过程是SQL用户定义表函数中的进一步包装,它编译和运行时都不会出错,但在传递作业名称(即当前作业)的“*”时,它会为作业信息返回空格和零。任何关于原因的提示都将不胜感激。注意:如果我传递了一个不存在的作业,那么QUSRJOBI api会正确地抛出一个错误,因此代码的行为部分正确。如果我传递了正确的活动工单名称、工单用户和工单编号,则不会发生错误,但仍会返回空格和零。我已经试过用CHAR(85)和VARCHAR(85)作为RECEIVER_变量。接下来,我将尝试对RECEIVER_变量使用二进制(85),但将二进制转换回CHAR和INT返回列可能会很困难

2) 一些OS/400API参数要求使用数据结构,而系统上V7R1上的DB2 SQL尚未直接支持数据结构(即,尚未直接支持结构化类型)。但是,表示可以使用二进制字符串实现,但未提供示例:(.经过广泛搜索,我还没有找到仅使用SQL对象包装OS400 api的示例。如果任何人有任何示例,说明如何仅使用SQL(由CHAR和其他数据类型(特别是INT)混合组成)来形成二进制字符串,请发布一个。api错误代码参数就是一个示例这是通常需要的。我将错误代码相关代码注释掉,因为如果重新激活该代码,它将生成错误CPF3CF1“错误代码参数无效”。如果有人能告诉我错误代码二进制字符串数据结构的形成方式有什么问题,请告诉我。我已经尝试了两个字符(16)和二进制(16)表示错误代码结构。我已经测试了错误代码形成的当前技术,将结果转储到表中,并在十六进制模式下使用DSPPFM查看表结果,使其看起来“二进制(十六进制(提供的错误代码字节))等工作正常。但是,我遗漏了一些东西

我知道有很多使用RPG包装OS/400API的例子,但我只想将这些包装作为SQL代码

create or replace procedure M_GET_JOB_INFORMATION
               ( out    OUT_RECEIVER_VARIABLE            char(85)
                ,in     IN_LENGTH_OF_RECEIVER_VARIABLE   int
                ,in     IN_FORMAT_NAME                   char(8)
                ,in     IN_QUALIFIED_JOB_NAME            char(26)
                ,in     IN_INTERNAL_JOB_IDENTIFIER       char(16)
           --     ,inout  INOUT_ERROR_CODE                 binary(16)  
               )

  program type main
  external name QSYS/QUSRJOBI

  parameter style general
  not deterministic
  modifies SQL data
  specific M_JOBINFO
  set option dbgview   = *source
            ,commit    = *nc
            ,closqlcsr = *endmod
            ,tgtrls    = V7R1M0 
;


create or replace function M_GET_JOB_INFORMATION_BASIC
                   ( IN_JOB_NAME                 varchar(10)
                    ,IN_JOB_USER                 varchar(10)
                    ,IN_JOB_NUMBER               varchar(6)
                    ,IN_INTERNAL_JOB_IDENTIFIER  varchar(16)
                   )
  returns table( JOB_NAME                 char(10)
                ,JOB_USER                 char(10)
                ,JOB_NUMBER               char(6)
                ,INTERNAL_JOB_IDENTIFIER  char(16)
                ,JOB_STATUS               char(10)
                ,JOB_TYPE                 char(1)
                ,JOB_SUBTYPE              char(1)
                ,RUN_PRIORITY             int
                ,TIME_SLICE               int
                ,DEFAULT_WAIT             int
                ,ELIGIBLE_FOR_PURGE       char(10)
               )

  language SQL
  specific M_JOBINFBF
  not deterministic
  disallow parallel
  no external action
  modifies SQL data
  returns null on null input
  not fenced

  set option dbgview   = *source
            ,commit    = *nc
            ,closqlcsr = *endmod
            ,tgtrls    = V7R1M0
     --       ,output    = *PRINT

begin

declare RECEIVER_VARIABLE             char(85)      default '';          --receives "JOBI0100" format output from API
declare LENGTH_OF_RECEIVER_VARIABLE   int           default 85;          --length of "JOBI0100" Format
declare FORMAT_NAME                   char(8)       default 'JOBI0100';  --basic job information
declare QUALIFIED_JOB_NAME            char(26);
declare INTERNAL_JOB_IDENTIFIER       char(16);
declare ERROR_CODE                    binary(16);  

--ERROR_CODE "ERRC0100" Format:
declare ERROR_CODE_BYTES_PROVIDED               int         default 8;    --Size of API Error Code data structure passed to API
declare ERROR_CODE_BYTES_RETURNED               int         default 0;    --Number of exception data bytes returned by the API
declare ERROR_CODE_EXCEPTION_ID                 char(7)     default '';   --Exception / error message ID returned by the API
declare ERROR_CODE_RESERVED                     char(1)     default '';   --Reserved bytes
declare ERROR_CODE_EXCEPTION_DATA               char(1)     default '';   --Exception data returned by the API

if IN_INTERNAL_JOB_IDENTIFIER = '' then 
   set QUALIFIED_JOB_NAME = char( IN_JOB_NAME, 10 ) || char( IN_JOB_USER, 10 ) || char( IN_JOB_NUMBER, 6 );
   set INTERNAL_JOB_IDENTIFIER = '';
else  
   set QUALIFIED_JOB_NAME = '*INT';
   set INTERNAL_JOB_IDENTIFIER = IN_INTERNAL_JOB_IDENTIFIER;   
end if;

set ERROR_CODE = binary( hex( ERROR_CODE_BYTES_PROVIDED ) ) ||  
                 binary( hex( ERROR_CODE_BYTES_RETURNED ) ) ||  
                 binary( ERROR_CODE_EXCEPTION_ID ) || 
                 binary( ERROR_CODE_RESERVED ) 
          --  ||    binary( ERROR_CODE_EXCEPTION_DATA )
;  

call M_GET_JOB_INFORMATION
        ( RECEIVER_VARIABLE             --out
         ,LENGTH_OF_RECEIVER_VARIABLE   --in
         ,FORMAT_NAME                   --in
         ,QUALIFIED_JOB_NAME            --in
         ,INTERNAL_JOB_IDENTIFIER       --in
      --   ,ERROR_CODE                    --in/out  --Results in error CPF3CF1 "Error code parameter not valid" if code line reactivated
        );

return values( char( substr( RECEIVER_VARIABLE,  8, 10 ), 10 )      --JOB_NAME
              ,char( substr( RECEIVER_VARIABLE, 18, 10 ), 10 )      --JOB_USER
              ,char( substr( RECEIVER_VARIABLE, 28,  6 ),  6 )      --JOB_NUMBER
              ,char( substr( RECEIVER_VARIABLE, 28, 16 ), 16 )      --INTERNAL_JOB_IDENTIFIER
              ,char( substr( RECEIVER_VARIABLE, 50, 10 ), 10 )      --JOB_STATUS
              ,char( substr( RECEIVER_VARIABLE, 60,  1 ),  1 )      --JOB_TYPE
              ,char( substr( RECEIVER_VARIABLE, 61,  1 ),  1 )      --JOB_SUBTYPE
              ,case when substr( RECEIVER_VARIABLE, 64, 4 ) = ''
                    then 0
                    else int( substr( RECEIVER_VARIABLE, 64, 4 ) )
               end                                                  --RUN_PRIORITY
              ,case when substr( RECEIVER_VARIABLE, 68, 4 ) = ''
                    then 0
                    else int( substr( RECEIVER_VARIABLE, 68, 4 ) )
               end                                                  --TIME_SLICE
              ,case when substr( RECEIVER_VARIABLE, 72, 10 ) = ''
                    then 0
                    else int( substr( RECEIVER_VARIABLE, 72, 4 ) )
               end                                                  --DEFAULT_WAIT
              ,char( substr( RECEIVER_VARIABLE, 76, 10 ), 10 )      --ELIGIBLE_FOR_PURGE
             )
;

end    
;
select * from table( M_GET_JOB_INFORMATION_BASIC( '*', '', '', '' ) ) as JOB_INFO
;

我在I 6.1中使用此函数调用QDBRTVFD API:

CREATE PROCEDURE SQLEXAMPLE.DBRTVFD ( 
    INOUT FD       CHAR(1024) , 
    IN    SZFD     INTEGER , 
    INOUT RTNFD    CHAR(20) , 
    IN    FORMAT   CHAR(8) , 
    IN    QF       CHAR(20) , 
    IN    "RCDFMT" CHAR(10) , 
    IN    OVRPRC   CHAR(1) , 
    IN    SYSTEM   CHAR(10) , 
    IN    FMTTYP   CHAR(10) , 
    IN    ERRCOD   CHAR(8) ) 
    LANGUAGE CL 
    SPECIFIC SQLEXAMPLE.DBRTVFD 
    NOT DETERMINISTIC 
    NO SQL 
    CALLED ON NULL INPUT 
    EXTERNAL NAME 'QSYS/QDBRTVFD' 
    PARAMETER STYLE GENERAL ;
首先,默认值是
语言C
,您可能不希望QUSRJOBI是一个OPM程序。在这里,传递CL语言参数对于可预测性来说是一个更好的选择

此外,您可能希望将其设置为
无SQL
,而不是
修改SQL数据
,因为您没有修改SQL数据。可能需要删除
设置选项
,以便将问题降到最低

如果您对M_GET_JOB_INFORMATION过程进行了这些更改,请查看它是否返回有用的值。如果没有,我们可以深入挖掘


对于您的特定API,我使用此代码在I 6.1上测试结果:

CREATE PROCEDURE SQLEXAMPLE.M_GET_JOB_INFORMATION ( 
    INOUT OUT_RECEIVER_VARIABLE CHAR(85) , 
    IN IN_LENGTH_OF_RECEIVER_VARIABLE INTEGER , 
    IN IN_FORMAT_NAME CHAR(8) , 
    IN IN_QUALIFIED_JOB_NAME CHAR(26) , 
    IN IN_INTERNAL_JOB_IDENTIFIER CHAR(16) , 
    IN IN_ERROR_CODE CHAR(8) ) 
    LANGUAGE CL 
    SPECIFIC SQLEXAMPLE.M_JOBINFO 
    NOT DETERMINISTIC 
    NO SQL 
    CALLED ON NULL INPUT 
    EXTERNAL NAME 'QSYS/QUSRJOBI' 
    PARAMETER STYLE GENERAL ;
创建了一个基本包装器,如下所示:

CREATE PROCEDURE SQLEXAMPLE.GENRJOBI ( 
    INOUT JOBI       VARCHAR(85) , 
    IN       QJOB      VARCHAR(26) ) 
    LANGUAGE SQL 
    SPECIFIC SQLEXAMPLE.GENRJOBI 
    NOT DETERMINISTIC 
    MODIFIES SQL DATA 
    CALLED ON NULL INPUT 
    SET OPTION  ALWBLK = *ALLREAD , 
        ALWCPYDTA = *OPTIMIZE , 
        COMMIT = *NONE , 
        DBGVIEW = *LIST , 
        CLOSQLCSR = *ENDMOD , 
        DECRESULT = (31, 31, 00) , 
        DFTRDBCOL = *NONE , 
        DLYPRP = *NO , 
        DYNDFTCOL = *NO , 
        DYNUSRPRF = *USER , 
        RDBCNNMTH = *RUW , 
        SRTSEQ = *HEX   
    P1 : BEGIN 
DECLARE JOBII CHAR ( 85 ) ; 
DECLARE SZJOBI INTEGER ; 
DECLARE FORMATI CHAR ( 8 ) ; 
DECLARE QJOBI CHAR ( 26 ) ; 
DECLARE JOBIDI CHAR ( 16 ) ; 
DECLARE ERRCODI CHAR ( 8 ) ; 
DECLARE STKCMD CHAR ( 10 ) ; 

SET JOBII = X'00000000' ; 
SET SZJOBI = 85 ;
SET FORMATI = 'JOBI0100' ; 
SET QJOBI = QJOB ; 
SET JOBIDI = '                ' ; 
SET ERRCODI = X'0000000000000000' ; 
SET STKCMD = '*LOG' ; 

CALL SQLEXAMPLE . M_GET_JOB_INFORMATION ( JOBII , SZJOBI ,  FORMATI , QJOBI , JOBIDI , ERRCODI ) ; 
CALL SQLEXAMPLE . LOGSTACK ( STKCMD ) ; 

SET JOBI = JOBII ; 

END P1  ;
包装器只提供了一个调用API proc的示例。它对API返回的结构不做任何处理,只将其传递回调用方。您最初的问题包括从结构中提取子字段的代码位,因此我不认为在这里放类似的代码有什么意义

这两个过程在iNav的“运行SQL脚本”中进行了测试,以获取有关我正在运行的交互式作业的信息,结果如下所示:


输出区域以字符显示结构,可以看到整数子字段与字符子字段混合在一起。根据需要解构结构。我可能会创建一个附加过程,将结构作为输入并返回单个结构元素。

您知道IBM已经包装了Get Job Info API吗

按版本/发布的所有服务

获取工作信息

1/5/2015更新版本:增强以使返回错误ID和错误数据的错误代码正常工作,并删除一些不必要的相关代码行。添加了M_HEX_STRING_to_INTEGER函数,用于在RECEIVER_变量中获取API返回的整数并将其转换为实整数。二进制(十六进制(my_int))代码没有如我所希望的那样工作,所以这个版本以十六进制传递错误代码“bytes provided”的大小。为了解决这个问题,我想我需要编写一个函数来获取一个整数并返回一个二进制(4),以便在二进制字符串应用程序中使用,直到IBM在系统I上给我们提供结构化类型。/更新结束

我解决了问题。主要问题是我调用的API是语言PLI,我想我错过了尝试该语言设置。我还有其他问题,包括忘记将一些偏移量转换为字节位置,我能够执行该操作的唯一方法是对与错误代码相关的代码使用VARBINARY。INOUT OUT\u RECEIVER\u变量需要。如果设置为OUT而不是INOUT,并且传递了无效的作业信息,则API程序将返回在上一次调用中返回的任何内容(返回上一次调用而非当前调用的剩余内存值)。我还必须编写一个函数来获取API返回的二进制INT数据,将其转换为实整数。如果我们有结构化类型(用户定义的数据结构)对于SQL和DB2的其他版本一样,我们可能可以避免大部分或所有二进制内容,从而使事情变得更简单

现在我已经整理好了包装这些API的基础知识,现在我应该能够非常快速地包装它们:)

--M_GET_JOB_INFORMATION(M_JOBINFO)—获取作业信息的外部SQL用户定义过程。
--围绕ibma的包装
--M_GET_JOB_INFORMATION (M_JOBINFO) - external SQL user defined procedure to fetch job information.

--Wrapper around IBM api QUSRJOBI (retrieve job information).

--May be used for any of the format data structures returned by the api, assuming a UDTF function has been created to consume the desired format data structure.

create or replace procedure M_GET_JOB_INFORMATION
               ( inout  RECEIVER_VARIABLE             char(86)  for bit data  --must use inout
                ,in     LENGTH_OF_RECEIVER_VARIABLE   int
                ,in     FORMAT_NAME                   char(8)
                ,in     QUALIFIED_JOB_NAME            char(26)
                ,in     INTERNAL_JOB_IDENTIFIER       char(16)
                ,inout  ERROR_CODE                    char(48)  for bit data
               )

  program type main
  external name 'QSYS/QUSRJOBI'
  language PLI
  parameter style general
  not deterministic
  modifies SQL data

  specific M_JOBINFO

  set option dbgview   = *source
            ,commit    = *nc
            ,closqlcsr = *endmod
            ,tgtrls    = V7R1M0   
;

--M_GET_JOB_INFORMATION_BASIC (M_JOBINFBF) - SQL user defined Table function to fetch job name, user, number, and other basic job information.

--Wrapper around IBM api QUSRJOBI retrieved data format JOBI0100 (basic job information).

--From IBM manual QUSRJOBI api:
  --The JOBI0100 format information is valid for active jobs and jobs on queues.
  --For jobs on queues, this format returns zeros or blanks for the attributes.
  --If the Change Job (CHGJOB) command was run against a job on a *JOBQ, the attributes returned are the attributes specified on the CHGJOB command.
  --If the job status changes to *OUTQ, the status field returned is *OUTQ and the API returns no information other than the number of bytes returned,
  --the number of bytes available, the qualified job name, the job type, the job subtype, and the internal job identifier.

--Examples of use:

  --select * from table( M_GET_JOB_INFORMATION_BASIC( '*', '', '', '' ) ) as JOB_INFO  --Get current job and basic info

  --select * from table( M_GET_JOB_INFORMATION_BASIC( 'QZDASOINIT', 'QUSER', '123456', '' ) ) as JOB_INFO  --Get a specific job's basic info

create or replace function M_GET_JOB_INFORMATION_BASIC
               ( IN_JOB_NAME                 varchar(10)
                ,IN_JOB_USER                 varchar(10)
                ,IN_JOB_NUMBER               varchar(6)
                ,IN_INTERNAL_JOB_IDENTIFIER  varchar(16)
               )

  returns table( JOB_NAME                    char(10)
                ,JOB_USER                    char(10)
                ,JOB_NUMBER                  char(6)
                ,INTERNAL_JOB_IDENTIFIER     char(16)
                ,JOB_STATUS                  char(10)
                ,JOB_TYPE                    char(1)
                ,JOB_SUBTYPE                 char(1)
                ,RUN_PRIORITY                int
                ,TIME_SLICE                  int
                ,DEFAULT_WAIT                int
                ,ELIGIBLE_FOR_PURGE          char(10)
                ,ERROR_ID                    char(7)   --returned as blank if valid job requested, else IBM error message ID returned.
                ,ERROR_DATA                  char(32)  --returned as blank if valid job requested, else IBM error message data returned.
               )

  language SQL
  specific M_JOBINFBF
  not deterministic
  disallow parallel
  no external action
  modifies SQL data
  called on null input
  not fenced
  cardinality 1  --helps SQL optimizer

  set option dbgview   = *source
            ,commit    = *nc
            ,closqlcsr = *endmod
            ,dftrdbcol = *none
            ,tgtrls    = V7R1M0

begin

declare RECEIVER_VARIABLE             char(86)    for bit data  default '';          --receives "JOBI0100" format output from API
declare LENGTH_OF_RECEIVER_VARIABLE   int                       default 86;          --length of "JOBI0100" Format
declare FORMAT_NAME                   char(8)                   default 'JOBI0100';  --basic job information
declare QUALIFIED_JOB_NAME            char(26);
declare INTERNAL_JOB_IDENTIFIER       char(16);
declare ERROR_CODE                    char(48)    for bit data  default '';  --ERROR_CODE "ERRC0100" Format - Input: bytes provided (4); Output: bytes available (4), error message ID (7), reserved bytes (1), error data (32) = 48 bytes

if IN_INTERNAL_JOB_IDENTIFIER = '' then
   set QUALIFIED_JOB_NAME = char( IN_JOB_NAME, 10 ) || char( IN_JOB_USER, 10 ) || char( IN_JOB_NUMBER, 6 );
   set INTERNAL_JOB_IDENTIFIER = '';
else
   set QUALIFIED_JOB_NAME = '*INT';
   set INTERNAL_JOB_IDENTIFIER = IN_INTERNAL_JOB_IDENTIFIER;
end if;

set ERROR_CODE = bx'00000030';  --put size of ERROR_CODE here in hex (Bytes Provided) hex 30 = dec 48

call M_GET_JOB_INFORMATION
        ( RECEIVER_VARIABLE             --in/out
         ,LENGTH_OF_RECEIVER_VARIABLE   --in
         ,FORMAT_NAME                   --in
         ,QUALIFIED_JOB_NAME            --in
         ,INTERNAL_JOB_IDENTIFIER       --in
         ,ERROR_CODE                    --in/out
        );

return values( char( substr( RECEIVER_VARIABLE,  9, 10 ), 10 )      --JOB_NAME
              ,char( substr( RECEIVER_VARIABLE, 19, 10 ), 10 )      --JOB_USER
              ,char( substr( RECEIVER_VARIABLE, 29,  6 ),  6 )      --JOB_NUMBER
              ,char( substr( RECEIVER_VARIABLE, 35, 16 ), 16 )      --INTERNAL_JOB_IDENTIFIER
              ,char( substr( RECEIVER_VARIABLE, 51, 10 ), 10 )      --JOB_STATUS
              ,char( substr( RECEIVER_VARIABLE, 61,  1 ),  1 )      --JOB_TYPE
              ,char( substr( RECEIVER_VARIABLE, 62,  1 ),  1 )      --JOB_SUBTYPE
              ,case when substr( RECEIVER_VARIABLE, 65, 4 ) = ''
                    then int( 0 )
                    else M_HEX_STRING_TO_INTEGER( hex( substr( RECEIVER_VARIABLE, 65, 4 ) ) )
               end                                                  --RUN_PRIORITY
              ,case when substr( RECEIVER_VARIABLE, 69, 4 ) = ''
                    then int( 0 )
                    else M_HEX_STRING_TO_INTEGER( hex( substr( RECEIVER_VARIABLE, 69, 4 ) ) )
               end                                                  --TIME_SLICE
              ,case when substr( RECEIVER_VARIABLE, 73, 10 ) = ''
                    then int( 0 )
                    else M_HEX_STRING_TO_INTEGER( hex( substr( RECEIVER_VARIABLE, 73, 4 ) ) )
               end                                                  --DEFAULT_WAIT
              ,char( substr( RECEIVER_VARIABLE, 77, 10 ), 10 )      --ELIGIBLE_FOR_PURGE
              ,char( substr( ERROR_CODE,  9, min( M_HEX_STRING_TO_INTEGER( hex( substr( ERROR_CODE, 5, 4 ) ) ),  7 ) ), 7 )   --ERROR_ID
              ,char( substr( ERROR_CODE, 17, min( M_HEX_STRING_TO_INTEGER( hex( substr( ERROR_CODE, 5, 4 ) ) ), 32 ) ), 32 )  --ERROR_DATA
             );

end
;

--M_HEX_STRING_TO_INTEGER - M_HEXTOINT - scalar SQL UDF to convert a hex string of an integer to an integer return value

--Use for working with binary strings and OS/400 system APIs.

--Throws an error if an invalid byte is found inside the input hex string.

create or replace function M_HEX_STRING_TO_INTEGER
   ( IN_HEX_STRING varchar(8) )

returns int

  language SQL
  specific M_HEXTOINT
  not deterministic
  disallow parallel
  no external action
  modifies SQL data
  returns null on null input
  not fenced

  set option dbgview   = *source
            ,commit    = *nc
            ,closqlcsr = *endmod
            ,tgtrls    = V7R1M0

begin

declare BYTE_CHAR      char(1);
declare POS            int        default 1;
declare ACCUM_VALUE    int;
declare BIGINT_RESULT  bigint     default 0;
declare STRING_LENGTH  int;

set STRING_LENGTH = length( IN_HEX_STRING );

while POS <= STRING_LENGTH do
   set BYTE_CHAR = substr( IN_HEX_STRING, POS, 1 );

   if BYTE_CHAR between '0' and '9' then
      set ACCUM_VALUE = int( BYTE_CHAR );
   else
      set ACCUM_VALUE = case BYTE_CHAR
                             when 'A' then 10
                             when 'B' then 11
                             when 'C' then 12
                             when 'D' then 13
                             when 'E' then 14
                             when 'F' then 15
                             else raise_error( 'MG010', 'Function M_HEX_STRING_TO_INTEGER encountered invalid INT hex byte=' || BYTE_CHAR )
                        end;
   end if;

   if ACCUM_VALUE <> 0 then
      set BIGINT_RESULT = BIGINT_RESULT + ( ACCUM_VALUE * power( 16, STRING_LENGTH - POS ) ) ;
   end if;

   set POS = POS + 1;
end while;

return int( case when BIGINT_RESULT > 2147483647 then BIGINT_RESULT - 4294967296 else BIGINT_RESULT end );

end