微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

相当于 Convert(VARBINARY) 的 Oracle/PL SQL

如何解决相当于 Convert(VARBINARY) 的 Oracle/PL SQL

我正在寻找在 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),2,1)) AS POS2,3,1)) AS POS3,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)),ASCII(SUBSTR(CAST('37000' AS RAW(8)),5,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 MOD( FLOOR( value / (256*256*256) ),256 ) AS pos1,MOD( FLOOR( value / (256*256)     ),256 ) AS pos2,MOD( FLOOR( value / 256           ),256 ) AS pos3,MOD( value,256 ) AS pos4
FROM   table_name

然后,对于您的示例数据:

CREATE TABLE table_name ( value ) AS
SELECT 37000 FROM DUAL;

它输出:

POS1 | POS2 | POS3 | POS4
---: | ---: | ---: | ---:
   0 |    0 |  144 |  136

如果您希望它是 4 字节的 RAW,则在十六进制转换中添加 FM 格式模型以去除前导空格并使用 0XXXXXXX 获得 4 字节带前导零:

SELECT HEXTORAW(TO_CHAR(value,'FM0XXXXXXX')) AS raw_value
FROM table_name;

输出:

| RAW_VALUE  |
| :--------- |
| 0x00009088 |

dbfiddle here

,

这件事:

select HEXTORAW(to_char(37000,'XXXXXXXX')) from dual

返回错误,因为默认情况下 to_char 会在您的数字的十六进制表示的左侧添加一个空格,而 hextoraw 不够聪明,无法知道如何处理它。 (这是数字代数符号 + 或更重要的是 - 的占位符)。

要解决此问题,您必须使用 fm 格式修饰符,这会导致生成的十六进制值省略前导空格。

另外,“XXXXXXXX”模型会导致省略前导零。如果要使原始值的长度为 4 个字节(而不是长度为 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,144,136 

所以,总而言之,您对 hextoraw 的尝试是在正确的道路上,但您需要在整数到十六进制字符串的转换中使用非常精确的格式模型(避免前导空格,包括前导零) ;而且,如果您真的想查看结果数据类型和所有字节,则必须使用 dump。请记住 dump - 结果证明它在许多不同的上下文中都非常有用。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?