oracle - Oracle/PL SQL 等效于 Convert(VARBINARY)
问题描述
我正在寻找在 MS SQL 中很容易做到的 Oracle 等价物,即:
DECLARE @INDEC AS INT
SET @INDEC = 37000
RIGHT(CONVERT(VARBINARY(8),@INDEC),4)
这复制了 MS SQL 数据库中的旧软件数据存储格式。相同的软件可以在 oracle 上运行,我现在需要在那里复制相同的语句。
具体来说,当我查看这个字符的结果时,我看到了一组独特的 ASCII 值:
SELECT
ASCII(SUBSTRING(RIGHT(CONVERT(VARBINARY(8),37000),4),1,1)) AS POS1,
ASCII(SUBSTRING(RIGHT(CONVERT(VARBINARY(8),37000),4),2,1)) AS POS2,
ASCII(SUBSTRING(RIGHT(CONVERT(VARBINARY(8),37000),4),3,1)) AS POS3,
ASCII(SUBSTRING(RIGHT(CONVERT(VARBINARY(8),37000),4),4,1)) AS POS4
FROM MYTABLE
POS1 | POS2 | POS3 | POS4 |
---|---|---|---|
0 | 0 | 144 | 136 |
当我在 Oracle 上尝试使用 CAST 作为 RAW 时,我要么将输入值返回给我,要么收到错误消息。
我专门尝试了各种转换选项,包括指定数据的长度以及在转换为原始数据之前将输入转换为十六进制。
SELECT
ASCII(SUBSTR(CAST('37000' AS RAW(8)),3,1)) AS POS1,
ASCII(SUBSTR(CAST('37000' AS RAW(8)),4,1)) AS POS2,
ASCII(SUBSTR(CAST('37000' AS RAW(8)),5,1)) AS POS3,
ASCII(SUBSTR(CAST('37000' AS RAW(8)),6,1)) AS POS4
FROM dual;
这只是返回“7000”或:
POS1 | POS2 | POS3 | POS4 |
---|---|---|---|
55 | 48 | 48 | 48 |
如果我先尝试转换为十六进制,我会收到一条错误消息(十六进制数无效):
select HEXTORAW(to_char(37000,'XXXXXXXX')) from dual
如果我分开转换,我知道 37000 的十六进制是 9088。但以下返回输入字符串(我已将其拆开。)
select HEXTORAW('9088') from dual
最终,此转换操作的输出将与其他字符串数据连接并存储在定义为 VARCHAR 的列中。
我觉得我在这里遗漏了一些非常基本的东西。
任何想法或意见将不胜感激。
解决方案
这东西:
select HEXTORAW(to_char(37000,'XXXXXXXX')) from dual
返回一个错误,因为默认情况下to_char
会在您的数字的十六进制表示的左侧添加一个空格,并且hextoraw
不够聪明,不知道如何处理它。(这是数字的代数符号的占位符,+
或者,更重要的是,-
)。
要解决此问题,您必须使用fm
格式修饰符,这会导致生成的十六进制值省略前导空格。
另外,“XXXXXXXX”模型会导致前导零被省略。如果要使原始值的长度为四个字节(而不是长度为 2,这将由转换整数 37000 产生),则需要在格式模型中使用 0 而不是 X,至少对于第一个数字(从左至右)。模型中的最后一个数字占位符(右侧)仍必须为 X 以表示十六进制。
所以,我们只剩下这个:
select hextoraw(to_char(37000, 'fm0XXXXXXX')) as converted_to_raw
from dual;
CONVERTED_TO_RAW
----------------
00009088
你不能通过查看这个查询的结果来判断(它看起来像一个十六进制数字),但该值确实是 RAW 数据类型,长度为 4,并且字节是你在 SQL Server 中获得的字节(我假设这就是您所说的 MS SQL 的意思)。在 Oracle 中,您可以使用该dump
函数同时查看数据类型(23 表示 RAW)和确切的字节数。默认情况下,它以十进制表示法显示字节(这正是您从 SQL Server 中显示的内容)。它看起来像这样:
select dump(hextoraw(to_char(37000, 'fm0XXXXXXX'))) as converted_to_raw
from dual;
CONVERTED_TO_RAW
------------------------------
Typ=23 Len=4: 0,0,144,136
因此,总而言之,您的尝试hextoraw
是正确的,但是您需要在整数到十六进制字符串的转换中使用非常精确的格式模型(避免前导空格,包括前导零);而且,如果您真的想查看生成的数据类型和所有字节,则必须使用dump
. 请记住dump
- 它在许多不同的情况下都非常有用。
推荐阅读
- python - 我可以从 HDF5 数据集中删除元素吗?
- java - remember username and password checkbox
- c++ - Visual Studio 15.7 Update: change in constructor inheritance
- javascript - Pubnub sending messages multiple times
- android - Firebase Auth getIdToken 更新后卡住了
- r - 我想在 R 中编写一个计算岭回归标准的方程
- hikaricp - 快速数据的 spring.datasource.driver-class-name
- python - RDD map+sortByKey - 错误理解列表python
- string - 在带有 VBA 的文本中查找单词(但不在另一个单词中)
- assembly - x86 程序集中的冲突符号:movsx 然后是无符号比较/分支?