数字在Oracle Merge Query中限制为9位数?

时间:2015-08-28 12:01:21

标签: oracle oracle-sqldeveloper

我正在尝试使用oracle db(11g)中的参数进行合并查询。我遇到了一个困扰我的问题。当我使用大于9位的数字为SESSION_ID运行查询时,不会发生匹配,并且在SESSION_ID设置为0的情况下创建新行。

表:

CREATE TABLE CLASSES ("SESSION_ID" NUMBER(19,0), "CLASS_NAME" NCHAR(255))

对于SESSION_ID:

,此查询适用于任意数量的数字,最多19位
MERGE INTO CLASSES db
USING (select 22507410978 AS SESSION_ID from dual) geo
ON (geo.SESSION_ID = db.SESSION_ID)
WHEN MATCHED THEN
UPDATE SET db.CLASS_NAME = 'My Class Name'
WHEN NOT MATCHED THEN
INSERT (db.SESSION_ID, db.CLASS_NAME) VALUES (22507410978, 'My Class Name');

此查询适用于任意数量的数字,最多9位。在9位数之后,SESSION_ID设置为0.(我正在使用SQL Developer测试它并通过ENTER BIND对话框输入SESSION_ID和CLASS_NAME的值。

MERGE INTO CLASSES db
USING (select :session_id AS SESSION_ID from dual) geo
ON (geo.SESSION_ID = db.SESSION_ID)
WHEN MATCHED THEN UPDATE SET db.CLASS_NAME = :class_name
WHEN NOT MATCHED THEN
INSERT (db.SESSION_ID, db.CLASS_NAME) VALUES (:session_id, :class_name);

因此,此值适用于SESSION_ID(2250741091)但不会(22507410911)。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

问题与您尝试执行merge语句无关。但是,在使用Enter Binds对话框时,Oracle SQL Developer如何绑定数字变量似乎是一个限制(错误?)。

当您键入绑定变量的值时,它会尝试明智地确定您输入的值的数据类型。如果它检测到一个数字,它会尝试将其绑定为4字节有符号整数值。但是,如果您的数字对于4字节有符号整数值(小于-1,147,483,648或大于1,147,483,647)而言太大,则绑定将失败并设置默认值0。 (我不知道我在本段中所描述的内容都是事实,但测试表明必须继续沿着这些方向发展)

避免可以考虑的事情"越野车" SQL Developer中的行为,考虑通过在脚本中提前定义和设置绑定变量值来完全绕过Enter Binds对话框。

例如,如果在SQL Developer中运行以下命令,它将不会提示您输入绑定值,并且您会发现插入的值是正确的:

var session_id number
var class_name nchar(255)
begin
  :session_id := 22507410978;
  :class_name := 'My Class Name';

  MERGE INTO CLASSES db
  USING (select :session_id AS SESSION_ID from dual) geo
  ON (geo.SESSION_ID = db.SESSION_ID)
  WHEN MATCHED THEN UPDATE SET db.CLASS_NAME = :class_name
  WHEN NOT MATCHED THEN
  INSERT (db.SESSION_ID, db.CLASS_NAME) VALUES (:session_id, :class_name);
end;
/

修改

David Aldridge提出了将绑定值作为文本值输入的有趣想法,然后让SQL将其转换回数字,方法是更改​​SQL:

to_number(:session_id)

不幸的是,Enter Binds对话框不允许您在输入值时指定数据类型。因此,即使您的SQL语句需要字符串值,当您在提示符中键入22507410978时,它将检测到输入的值看起来像一个数字,并将尝试将值(错误地)转换为4字节有符号整数,结果值0

更进一步,这实际上意味着绑定到:class_name列的nchar绑定变量如果输入的数量非常大,也可能会中断。如果您尝试原始测试,并在系统提示输入22507410978值时输入:class_name,则会在0列中看到字符class_name已插入

根据我的观察,如果我是你,我会尽可能远离Enter Binds对话框。