Oracle SELECT - 双引号还是不用双引号?
Oracle SELECT - 双引号还是不用双引号?
大家好,
在编写针对Oracle 11i数据库的SELECT查询时,为什么在Oracle中有些表必须使用引号来选择字段,而其他表则不需要呢?
最近我遇到了一个例子:
在Aqua Data Studio的查询分析器窗口中,我尝试从两个不同的表中选择相同的字段:
select _id from table1 select _id from table2
table1和table2有很大的区别,但只有table1可以执行这个select语句而不会出错。当我尝试执行table2的这个语句时,会出现以下错误:
ORA-00904: "_ID": 无效标识符 脚本行1,语句行1,列7
然而,当我像这样执行第二个语句时,它完全正常工作:
select "_id" from table2
有人知道这里发生了什么情况吗?为什么会这样,以及导致表之间的关键差异可能是什么呢?
谢谢
Oracle SELECT语句中使用双引号的原因是由于列名以下划线开头,而客户端通常会隐藏引号。如果尝试创建一个没有用引号引起来的名为_id
的列的表,则会出现'ORA-00911: invalid character'错误,错误信息显示'identifiers may not start with any ASCII character other than letters and numbers',这实际上是错误的,因为它也不能以数字开头(例如,0_id
会报错'ORA-00904: : invalid identifier')。这得到了数据库对象命名规则的支持:
未引用的标识符必须以数据库字符集中的字母字符开头。引用标识符可以以任何字符开头。
因此,Aqua Data Studio似乎遵循了将提供的对象名的大写版本用双引号括起来的惯例,这在其中一个链接的帖子中提到过。
从您提供的内容来看,select _id from ...
会作为select "_ID" from ...
传递给Oracle,如果列名是"_ID"
创建的话,这是可以的。看起来table1
是这种情况,但table2
是以"_id"
的形式创建的,所以这种大小写不匹配导致了您看到的合法ORA-00904错误。
如果列名已经被双引号引起来,那么您的客户端不会修改它,因此select "_id" from ...
会原样传递给Oracle,对于table2
是可以工作的(但相反,对于table1
则会失败)。
如果名称不符合未引用标识符的规则,Oracle要求将其用双引号括起来,如果它是以引号引起来的形式创建的-除非原始的引号值仍然有效,即遵循未引用规则并以大写形式输入。由于列名以下划线开头,Oracle认为无论大小写如何,对它的所有引用都必须用双引号括起来。如果您没有自己引用它,您的客户端将在后台执行此操作。
遵循其他人提出的避免使用引号标识符并始终使用有效的未引用名称的建议将避免此类问题的出现。
在Oracle中,当创建对象时,出现了一个问题。如果你使用小写字母和引号创建一个对象,它将强制区分大小写。因此,你需要使用引号和正确的大小写来使用它。如果你不使用引号(或全部使用大写),你就不会遇到任何“大小写敏感性”问题,并且可以选择具有小写或大写的对象(无需引号)。
问题的解决方法是,在创建对象时,根据需要使用引号或不使用引号来处理大小写敏感性。如果你想要强制区分大小写,你需要使用引号,并确保引号内的字符与对象的大小写一致。如果你不想要大小写敏感性,只需使用大写字母创建对象即可,无需引号。
以下是解决问题的示例代码:
1. 创建对象时使用引号和正确的大小写:
CREATE TABLE "myTable" ( "ID" NUMBER, "Name" VARCHAR2(100) );
2. 创建对象时不使用引号,并使用大写字母:
CREATE TABLE MYTABLE ( ID NUMBER, NAME VARCHAR2(100) );
通过根据需要使用引号或不使用引号来处理大小写敏感性问题,你可以在Oracle中正常使用对象,并且能够选择具有不同大小写的对象。