Aar*_*uth 5 sql string oracle variables binding
我正在使用 Oracle SQL Developer 4.0.1.14 并试图找出一些变量绑定。我从以下查询开始:
SELECT *
FROM Ships
WHERE UniqueId = 17;
Run Code Online (Sandbox Code Playgroud)
和
SELECT *
FROM Ships
WHERE UniqueId = :variable;
Run Code Online (Sandbox Code Playgroud)
这两个都成功执行。当您运行第二个时,Oracle SQL Developer 会提示您输入一个值,我输入了 17。但是,当我尝试使用字符串参数执行相同操作时,我没有成功(查询返回 0 行)。例如:
SELECT *
FROM Ships
WHERE ShipName = 'Atlantic Boat';
Run Code Online (Sandbox Code Playgroud)
和
SELECT *
FROM Ships
WHERE ShipName LIKE :variable;
Run Code Online (Sandbox Code Playgroud)
只有第一次查询成功。我试过进入弹出窗口
大西洋船
《大西洋之舟》
《大西洋船》
和其他变化没有成功。我怎样才能使这项工作?
编辑:我尝试使用类似语句并发现了一些成功。
SELECT *
FROM Ships
WHERE ShipName LIKE '%Atlantic Boat%';
Run Code Online (Sandbox Code Playgroud)
和
SELECT *
FROM Ships
WHERE ShipName LIKE :variable;
Run Code Online (Sandbox Code Playgroud)
两者实际上都有效。第二个需要 %Atlantic Boat%,没有字符串引号 ('')。然而,即使有 % 变化,我仍然无法让 = one 起作用。
如果表的名称定义为varchar2字段,则它按预期工作:
create table ships (uniqueid number, shipname varchar2(20));
insert into ships values (17, 'Atlantic Boat');
SELECT *
FROM Ships
WHERE ShipName = 'Atlantic Boat';
UNIQUEID SHIPNAME
---------- ------------------------------
17 Atlantic Boat
var variable varchar2(20);
anonymous block completed
exec :variable := 'Atlantic Boat';
SELECT *
FROM Ships
WHERE ShipName LIKE :variable;
UNIQUEID SHIPNAME
---------- ------------------------------
17 Atlantic Boat
Run Code Online (Sandbox Code Playgroud)
但是,如果该表有一char列,则它会显示您描述的行为:
drop table ships;
create table ships (uniqueid number, shipname char(20));
insert into ships values (17, 'Atlantic Boat');
SELECT *
FROM Ships
WHERE ShipName = 'Atlantic Boat';
UNIQUEID SHIPNAME
---------- ------------------------------
17 Atlantic Boat
var variable varchar2(20);
exec :variable := 'Atlantic Boat';
anonymous block completed
SELECT *
FROM Ships
WHERE ShipName LIKE :variable;
no rows selected
Run Code Online (Sandbox Code Playgroud)
即使声明了绑定变量,也会发生这种情况char(20)。
char值以空白填充存储到字段长度,因此在这种情况下,存储的值实际上是'Atlantic Boat ',末尾有 7 个空格。通常,当您进行比较时WHERE ShipName = 'Atlantic Boat',字符串文字会隐式转换为您要比较的列类型,并且在比较期间它们被视为相等。绑定变量似乎没有发生这种情况,但我无法立即在文档中看到对该行为的任何引用。
当您使用LIKE 'Atlantic Boat%'或Atlantic Boat%作为绑定变量传递时,额外的空格不再相关,因为完整'Atlantic Boat '的确实像Atlantic Boat%.
没有真正的理由使用char(有些像短标志或总是固定长度的字段char,但即使有也没什么区别)。解决此问题的最佳方法是更改表定义,使字段为varchar2.
如果你不能这样做,你可以在查询中转换绑定变量:
SELECT *
FROM Ships
WHERE ShipName LIKE cast(:variable as char(20));
UNIQUEID SHIPNAME
---------- ------------------------------
17 Atlantic Boat
Run Code Online (Sandbox Code Playgroud)