【问题标题】:Oracle SQL Developer String variable bindingOracle SQL Developer 字符串变量绑定
【发布时间】:2014-05-20 17:33:39
【问题描述】:

我正在使用 Oracle SQL Developer 4.0.1.14 并试图找出一些变量绑定。我从以下查询开始:

SELECT *
FROM Ships
WHERE UniqueId = 17;

SELECT *
FROM Ships
WHERE UniqueId = :variable;

这两个都成功执行。当您运行第二个时,Oracle SQL Developer 提示您输入一个值,我输入 17。但是,当我尝试对字符串参数执行相同操作时,我不成功(查询返回 0 行)。例如:

SELECT *
FROM Ships
WHERE ShipName = 'Atlantic Boat';

SELECT *
FROM Ships
WHERE ShipName LIKE :variable;

只有第一个查询成功。我已经尝试进入弹出窗口

大西洋船

“大西洋之船”

“大西洋之船”

和其他变体没有成功。我怎样才能做到这一点?

编辑:我尝试过使用 like 语句并取得了一些成功。

SELECT *
FROM Ships
WHERE ShipName LIKE '%Atlantic Boat%';

SELECT *
FROM Ships
WHERE ShipName LIKE :variable;

两者都有效。第二个需要 %Atlantic Boat%,没有字符串引号 ('')。但是,即使有 % 的变化,我仍然无法让 = one 工作。

【问题讨论】:

  • 既然返回0行,你确定ShipName列中有这个值Atlantic Boat吗?
  • 对不起,如果我不清楚。第三个查询 (ShipName = 'Atlantic Boat') 返回我正在寻找的行,所以我确定它存在。只有第 4 个查询返回 0 行
  • 这在 4.0.1.14 和 4.0.2.15 中对我来说很好用。在绑定窗口中输入值时不应有任何引号,但您显示的第一个值应该有效。 建议这不是您输入的内容;要么情况略有不同,要么你有一个前导或尾随空格,或者类似的东西。或者,更有可能的是,您的字段被声明为 char 而不是 varchar2...
  • @AlexPoole 该列确实被声明为 CHAR(20 CHAR) 而不是 VARCHAR2。您能解释一下为什么会导致上述问题吗?

标签: sql string oracle variables binding


【解决方案1】:

如果表的名称定义为 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                  

但如果表格有 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

即使绑定变量也声明为 char(20),也会发生这种情况。

char 值存储在字段长度的空白处,因此在这种情况下,存储的值实际上是 'Atlantic Boat ',末尾有 7 个空格。通常,当您进行WHERE ShipName = 'Atlantic Boat' 之类的比较时,字符串文字与您要比较的列类型为implicitly converted,并且在比较期间它们被视为相等。绑定变量似乎没有发生这种情况,但我无法立即在文档中看到对该行为的任何引用。

当您使用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                  

【讨论】:

    【解决方案2】:

    我使用的是 SQL Developer 4.0.1.14,它确实在我这边工作,只通过 Atlantic Boat:

    正如@Alex Poole 在上面的评论中提到的,确保ShipName 的类型为varchar2。输入 desbribe Ships 以检查该信息:


    您也可以查看this SQL Fiddle。看到 like 'Atlantic Boat' 正确地获取了行。

    【讨论】:

    • 与原始查询有不同的含义(和可能的结果)。
    • @njzk2 他说查询返回 0 行。也许使用模式w3schools.com/sql/sql_like.asp 它会找到一些东西。
    猜你喜欢
    • 2017-07-09
    • 2020-03-20
    • 2017-06-30
    • 1970-01-01
    • 2015-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多