关于Oracle中的双引号和命名规则的一点猜想

© Young 2016-04-04 14:34
Welcome to My GitHub

基本前提

一直以为Oracle中的命名规则和java中变量的命名规则大同小异。

问题一

SQL> create table "liy" ("no" number,"name" varchar2(10));
SQL> Table created
SQL> select * from "liy";
            no name
    ---------- ----------

这个创建表的SQL在Oracle 11g中会执行成功,而且表空间确实存在该表,但是向该表插入数据的时候有一些要注意的地方。

SQL> insert into liy(no,name) values (14,'liy');
SQL> ORA-00942:表或者视图不存在

在插入数据的时候如果表名或者字段名不加双引号就会报错”表不存在,或者是字段未定义“。

但是下面这种方式却是可以的:

SQL> insert into "liy"("no","name") values (14,'liy');
SQL> 1 row inserted
SQL> select * from "liy";
            no name
    ---------- ----------
            14 liy

到这我就在猜想:难道表名和字段名都变成双引号加上字母的组合了?但是这不就和Oracle的命名规则相违背了吗?

注意到表中的字段名是小写的,然后又建了一张表,并插入数据

SQL> create table "LIY"("NO" number,"NAME" varchar2(10));
SQL> Table created
SQL> insert into "LIY"("NO","NAME") values(14,'liy');
SQL> 1 row inserted
SQL> select * from "LIY";
            NO NAME
    ---------- ----------
            14 liy

这种方式上边早就证明是可以成功的,奇怪的事情在下边:

SQL> insert into liy(no,name) values(35,'zth');
SQL> 1 row inserted
SQL> select * from "LIY";
            NO NAME
    ---------- ----------
            14 liy
            35 zth

上边假设过这种方式建表,表名和字段是双引号和字母的组合,但是如果假设成立的话不光违背了命名规则,而且上边的这种插入方式也不会成功,所以“表名和字段是双引号和字母的组合”的假设是错误的。

然后就涉及到双引号在Oracle中的作用,学习Oracle好几个月了,但是从来没有在Oracle中使用过双引号,因为在Oracle中字符串是用单引号表示的(好像大部分数据库都是这样),在网上查了一下,原来在Oracle中双引号的作用是:如果创建对象的时候,对象名,字段名加双引号,则表示Oracle将严格区分大小写,否则Oracle都 会默认大写。

以下SQL也许能证明:

SQL> create table ttt("NO" number,no number,name varchar2(10));
SQL> ORA-00957:重复的列名
SQL> create table ttt("no" number,no number,name varchar2(10));
SQL> Table created
SQL> select * from ttt;
            no         NO NAME
    ---------- ---------- ----------

可是就算了解双引号的作用还是有些疑问…

问题二:

SQL> create table t(no-*^-... number,name varchar2(10));
SQL> ORA-00902:无效数据类型
SQL> create table t(""no"" number,name varchar2(10));
SQL> ORA-01741:非法的零长度标识符
SQL> create table t("no-*^-..." number,name varchar2(10));
SQL> Table created
SQL> select * from t;
     no-*^-... NAME
    ---------- ----------

用双引号的字段名或表名可以有命名规则中不允许出现的非法字符,但是就是不能加入双引号它本身,这又是为什么呢?

小结(个人理解,不一定有道理)

这些都不好理解,我不知道Oracle在执行SQL的时候到底干了些什么,但是我们假定Oracle在执行SQL之前,进行词法与语法分析的时候有一个默认的方法(或者是运算)将所有没有被双引号包括的字母转换成大写的,然后按照自己的命名规则对所有对象名进行校验。而双引号也是一种方法(运算)它能抵消Oracle默认方法带来的变化(或者是阻止默认方法改变被它包括的字符),至于为什么双引号不能包括它自己,就把它类比算术运算中的操作符不能对操作符进行运算(5**//),或者是有参数的函数必须得传递参数。而所谓的Oracle的不区分大小写,实质上是Oracle默认都转换成大写的了,而双引号阻止转换后还是有大小写区别的。其实有一句话说得好,完全不用像上边那样纠结“在Oracle中没事就不要乱用双引号”。

发表评论

电子邮件地址不会被公开。 必填项已用*标注