如何将十六进制数据字符串转换为字符串 db2 sql
How to cast hex data string to a string db2 sql
如何使用 select 语句解码十六进制字符串以获取文本格式的值?
例如我的十六进制数据是:
4f004e004c005900200046004f00520020004200410043004b002d005500500020004f004e0020004c004500560045004c0020004f004e004500200046004f00520020004300520041004e004500530020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020000000
我想使用 select 语句对其进行解码以获取字符串值。
上面的值为"ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES"
我试过的是:
SELECT CAST('4f004e004c005900200046004f00520020004200410043004b002d005500500020004f004e0020004c004500560045004c0020004f004e004500200046004f00520020004300520041004e004500530020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020000000'
AS VARCHAR(30000) CCSID 37) from myschema.atable
上面的 sql returns 完全相同的十六进制字符串,而不是我预期的 "ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES" 的解码文本字符串。
是否可以通过演员阵容来做到这一点?如果是,语法是什么?
我遇到的问题是系统将文本数据存储在 blob 字段中,我想使用 select 语句查看 blob 字段中的文本数据。
Db:Ibm 上的 Db2
编辑:
我已经设法通过使用将字符串转换为十六进制值:
select hex(cast('ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES' as varchar(100) ccsid 1208))
FROM myschema.atable
这给了我十六进制的字符串:
4F4E4C5920464F52204241434B2D5550204F4E204C4556454C204F4E4520464F52204352414E4553
现在我需要以某种方式进行逆运算并获取值。
谢谢。
编辑
根据 Daniel Lema 的回答,我尝试使用 unhex 函数,但得到的结果是:
|+<ßã|êâ ä.í&|+<áîá<|+áã|êäê +áë
这与 CSSID 有关吗?或者我应该如何将以上内容转换为可读字符串?
这是 table 字段定义,如果它有助于我的数据字段是 GDTXFT BLOB :
我质疑你为什么需要这样做...
将十六进制字符串转换回其等效字符是有正当理由的...例如,有人向您发送了一个 32 字节的字符串 UUID,而您希望将其返回为 16 字节的二进制形式。
但没有理由 ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES
应该转换为十六进制。
我怀疑您需要 post 一个新问题,询问为什么您首先没有获得可读字符串。
但是,在回答这个问题时...IBM i 有一个 MI 函数 Convert Character to Hex (CVTCH),可以从任何 ILE 语言轻松调用。您可以将该函数调用包装到用户定义的函数中,以便在 SQL.
中使用它
请注意,您需要知道十六进制字符串代表什么,EBCDIC、ASCII 或 Unicode,因为您需要能够告诉系统您从什么开始。从那里可以在编码之间进行转换。
这里有一篇文章介绍了如何从 RPG 调用 MI 函数。
Utilizing MI Functions in RPG Programs
利用 CCSID 关键字增强功能的更现代的原型自由形式版本可能看起来像
dcl-pr FromHex extproc('cvtch');
charString char(32767) ccsid(*UTF8) options(*varsize);
hexString char(65534) ccsid(*HEX) const options(*varsize);
hexStringLen int(10) value;
end-pr;
如上原型,系统会将返回的字符串作为UTF8(ccsid 1208)处理。但我所做的只是告诉系统如何解释返回的字节。如果字符串实际上是 EBCDIC,我将得到垃圾。
我认为您甚至可以将 cvtch
函数直接定义为外部 UDF,而无需 ILE 包装器。我不得不尝试一下...
忽略那个想法...cvtch 只有参数,没有 return 值。使用 ILE 包装器是将输出参数移动到 return 值以用作 UDF 的最佳方法。
我尝试了以下由 Marcin Rudzki 在 Convert HEX value to CHAR on DB2 发布的解决方案,并在我自己的 Db2 中针对 LUW v11 进行了小的修改测试。
解决方案包括按照 Marcin 的建议创建一个函数:
CREATE FUNCTION unhex(in VARCHAR(32000) FOR BIT DATA)
RETURNS VARCHAR(32000)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC NO EXTERNAL ACTION
BEGIN ATOMIC
RETURN in;
END
为了测试解决方案,让我们创建一个 HEXSAMPLE table,其中的 HEXSTRING 列加载了 HEX 序列的字符串表示形式:
INSERT INTO HEXSAMPLE (HEXSTRING) VALUES ('4F4E4C5920464F52204241434B2D5550204F4E204C4556454C204F4E4520464F52204352414E4553')
然后执行以下查询(这里与原来的提议不同):
SELECT UNHEX(CAST(HEXTORAW(HEXSTRING) AS VARCHAR(2000) FOR BIT DATA)) as TEXT, HEXSTRING FROM HEXSAMPLE
结果:
TEXT HEXSTRING
---------------------------------------- --------------------------------------------------------------------------------
ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES 4F4E4C5920464F52204241434B2D5550204F4E204C4556454C204F4E4520464F52204352414E4553
我希望其他人可以找到更直接的解决方案。另外,如果有人能解释它为什么有效,那将是非常有趣的。
问题是您的原始字符串是 ASCII 格式(实际上每个字母后都有 x'00' 字节),您必须将其转换为 EBCDIC。
以下是仅适用于拉丁大写字母的解决方案:
select cast(translate(replace(mycol, x'00', x'')
, x'C1C2C3C4C5C6C7C8C9D1D2D3D4D5D6D7D8D9E2E3E4E5E6E7E8E940'
, x'4142434445464748494A4B4C4D4E4F505152535455565758595A20'
) as varchar(500) ccsid 37)
from mytab;
每个 ASCII 字符都转换为相应的 EBCDIC 字符。
x'00' 个符号被删除。
我能够将您缩短的十六进制字符串转换为有效的 EBCDIC 字符串。
我 运行 遇到的问题是您收到的原始十六进制代码是 UTF-16LE(感谢 Tom Blodget)。 IBM 的 CCSID 系统在 UTF-16BE 和 UTF-16LE 之间没有区别,所以我不知道如何正确转换它。
如果它是您稍后生成的 UTF-8 格式,则以下内容对您有用。它不是最漂亮的,但将它放入几个函数中,它会起作用。
Create or replace function unpivothex (in_ varchar(30000))
returns table (Hex_ char(2), Position_ int)
return
with returnstring (ST , POS )
as
(Select substring(STR,1,2), 1
from table(values in_) as A(STR)
union all
Select nullif(substring(STR,POS+2,2),'00'), POS+2
from returnstring, table(values in_) as A(STR)
where POS+2 <= length(in_)
)
Select ST, POS
from returnstring
;
Create or replace function converthextostring
(in_string char(30000))
returns varchar(30000)
return
(select listagg(char(varbinary_format(B.Hex_),1)) within group(order by In_table.Position_)
from table(unpivothex(upper(in_string))) in_table
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 1208)))) A on In_table.Hex_ = A.Hex_
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 37)))) B on A.Position_ = B.Position_
);
如果您至少未使用 V7R2 TR6 或 V7R3 TR2,请查看此版本。
Create or replace function converthextostring
(in_string char(30000))
returns varchar(30000)
return
(select xmlserialize(
xmlagg(
xmltext(cast(char(varbinary_format(B.Hex_),1) as char(1) CCSID 37))
order by In_table.Position_)
as varchar(30000))
from table(unpivothex(upper(in_string))) in_table
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 1208)))) A on In_table.Hex_ = A.Hex_
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 37)))) B on A.Position_ = B.Position_
);
cast (col_name as varchar(2000) ccsid ascii for sbcs data)
如何使用 select 语句解码十六进制字符串以获取文本格式的值?
例如我的十六进制数据是:
4f004e004c005900200046004f00520020004200410043004b002d005500500020004f004e0020004c004500560045004c0020004f004e004500200046004f00520020004300520041004e004500530020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020000000
我想使用 select 语句对其进行解码以获取字符串值。 上面的值为"ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES"
我试过的是:
SELECT CAST('4f004e004c005900200046004f00520020004200410043004b002d005500500020004f004e0020004c004500560045004c0020004f004e004500200046004f00520020004300520041004e004500530020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020002000200020000000'
AS VARCHAR(30000) CCSID 37) from myschema.atable
上面的 sql returns 完全相同的十六进制字符串,而不是我预期的 "ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES" 的解码文本字符串。
是否可以通过演员阵容来做到这一点?如果是,语法是什么?
我遇到的问题是系统将文本数据存储在 blob 字段中,我想使用 select 语句查看 blob 字段中的文本数据。
Db:Ibm 上的 Db2
编辑:
我已经设法通过使用将字符串转换为十六进制值:
select hex(cast('ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES' as varchar(100) ccsid 1208))
FROM myschema.atable
这给了我十六进制的字符串:
4F4E4C5920464F52204241434B2D5550204F4E204C4556454C204F4E4520464F52204352414E4553
现在我需要以某种方式进行逆运算并获取值。
谢谢。
编辑
根据 Daniel Lema 的回答,我尝试使用 unhex 函数,但得到的结果是:
|+<ßã|êâ ä.í&|+<áîá<|+áã|êäê +áë
这与 CSSID 有关吗?或者我应该如何将以上内容转换为可读字符串?
这是 table 字段定义,如果它有助于我的数据字段是 GDTXFT BLOB :
我质疑你为什么需要这样做...
将十六进制字符串转换回其等效字符是有正当理由的...例如,有人向您发送了一个 32 字节的字符串 UUID,而您希望将其返回为 16 字节的二进制形式。
但没有理由 ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES
应该转换为十六进制。
我怀疑您需要 post 一个新问题,询问为什么您首先没有获得可读字符串。
但是,在回答这个问题时...IBM i 有一个 MI 函数 Convert Character to Hex (CVTCH),可以从任何 ILE 语言轻松调用。您可以将该函数调用包装到用户定义的函数中,以便在 SQL.
中使用它请注意,您需要知道十六进制字符串代表什么,EBCDIC、ASCII 或 Unicode,因为您需要能够告诉系统您从什么开始。从那里可以在编码之间进行转换。
这里有一篇文章介绍了如何从 RPG 调用 MI 函数。 Utilizing MI Functions in RPG Programs
利用 CCSID 关键字增强功能的更现代的原型自由形式版本可能看起来像
dcl-pr FromHex extproc('cvtch');
charString char(32767) ccsid(*UTF8) options(*varsize);
hexString char(65534) ccsid(*HEX) const options(*varsize);
hexStringLen int(10) value;
end-pr;
如上原型,系统会将返回的字符串作为UTF8(ccsid 1208)处理。但我所做的只是告诉系统如何解释返回的字节。如果字符串实际上是 EBCDIC,我将得到垃圾。
我认为您甚至可以将 cvtch
函数直接定义为外部 UDF,而无需 ILE 包装器。我不得不尝试一下...
忽略那个想法...cvtch 只有参数,没有 return 值。使用 ILE 包装器是将输出参数移动到 return 值以用作 UDF 的最佳方法。
我尝试了以下由 Marcin Rudzki 在 Convert HEX value to CHAR on DB2 发布的解决方案,并在我自己的 Db2 中针对 LUW v11 进行了小的修改测试。
解决方案包括按照 Marcin 的建议创建一个函数:
CREATE FUNCTION unhex(in VARCHAR(32000) FOR BIT DATA)
RETURNS VARCHAR(32000)
LANGUAGE SQL
CONTAINS SQL
DETERMINISTIC NO EXTERNAL ACTION
BEGIN ATOMIC
RETURN in;
END
为了测试解决方案,让我们创建一个 HEXSAMPLE table,其中的 HEXSTRING 列加载了 HEX 序列的字符串表示形式:
INSERT INTO HEXSAMPLE (HEXSTRING) VALUES ('4F4E4C5920464F52204241434B2D5550204F4E204C4556454C204F4E4520464F52204352414E4553')
然后执行以下查询(这里与原来的提议不同):
SELECT UNHEX(CAST(HEXTORAW(HEXSTRING) AS VARCHAR(2000) FOR BIT DATA)) as TEXT, HEXSTRING FROM HEXSAMPLE
结果:
TEXT HEXSTRING
---------------------------------------- --------------------------------------------------------------------------------
ONLY FOR BACK-UP ON LEVEL ONE FOR CRANES 4F4E4C5920464F52204241434B2D5550204F4E204C4556454C204F4E4520464F52204352414E4553
我希望其他人可以找到更直接的解决方案。另外,如果有人能解释它为什么有效,那将是非常有趣的。
问题是您的原始字符串是 ASCII 格式(实际上每个字母后都有 x'00' 字节),您必须将其转换为 EBCDIC。
以下是仅适用于拉丁大写字母的解决方案:
select cast(translate(replace(mycol, x'00', x'')
, x'C1C2C3C4C5C6C7C8C9D1D2D3D4D5D6D7D8D9E2E3E4E5E6E7E8E940'
, x'4142434445464748494A4B4C4D4E4F505152535455565758595A20'
) as varchar(500) ccsid 37)
from mytab;
每个 ASCII 字符都转换为相应的 EBCDIC 字符。
x'00' 个符号被删除。
我能够将您缩短的十六进制字符串转换为有效的 EBCDIC 字符串。 我 运行 遇到的问题是您收到的原始十六进制代码是 UTF-16LE(感谢 Tom Blodget)。 IBM 的 CCSID 系统在 UTF-16BE 和 UTF-16LE 之间没有区别,所以我不知道如何正确转换它。
如果它是您稍后生成的 UTF-8 格式,则以下内容对您有用。它不是最漂亮的,但将它放入几个函数中,它会起作用。
Create or replace function unpivothex (in_ varchar(30000))
returns table (Hex_ char(2), Position_ int)
return
with returnstring (ST , POS )
as
(Select substring(STR,1,2), 1
from table(values in_) as A(STR)
union all
Select nullif(substring(STR,POS+2,2),'00'), POS+2
from returnstring, table(values in_) as A(STR)
where POS+2 <= length(in_)
)
Select ST, POS
from returnstring
;
Create or replace function converthextostring
(in_string char(30000))
returns varchar(30000)
return
(select listagg(char(varbinary_format(B.Hex_),1)) within group(order by In_table.Position_)
from table(unpivothex(upper(in_string))) in_table
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 1208)))) A on In_table.Hex_ = A.Hex_
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 37)))) B on A.Position_ = B.Position_
);
如果您至少未使用 V7R2 TR6 或 V7R3 TR2,请查看此版本。
Create or replace function converthextostring
(in_string char(30000))
returns varchar(30000)
return
(select xmlserialize(
xmlagg(
xmltext(cast(char(varbinary_format(B.Hex_),1) as char(1) CCSID 37))
order by In_table.Position_)
as varchar(30000))
from table(unpivothex(upper(in_string))) in_table
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 1208)))) A on In_table.Hex_ = A.Hex_
join table(unpivothex(hex(cast('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ' as char(53) CCSID 37)))) B on A.Position_ = B.Position_
);
cast (col_name as varchar(2000) ccsid ascii for sbcs data)