我正在尝试使用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)。
有什么想法吗?
答案 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
对话框。