Oracle中的 单引号 和 双引号【待整理】

来源:互联网 发布:淘宝开店代销要钱吗 编辑:程序博客网 时间:2024/06/06 15:53

在Oracle中:
  双引号的作用是:假如建立对象的时候,对象名、字段名加双引号,则示意Oracle将严格区分大小写,否则Oracl都默认大写。

  而单引号则示意:这个加了单引号的字段是一个字类似字符串,并不区分大小写。

单引号用于标识字符与数字的区别

  当指定字符串文本时,必须用单引号将字符串文本引住。

  Oracle10g之前,假如字符串文本里含有单引号,那么必须运用两个单引号示意。例如:I'm a String!

  字符串文本则为:string_var:='I''m a String!'

  在oracle10g中可以运用其它分隔符(<>,[],{}等),留心,运用这些分隔符时,不仅要在分隔符前后加单引号,还要带有前缀q.例:string_var:=q'[I''m a String!]';

  例如

  select * from table_name where id=1;这种代表查询的是数字

  select * from table_name where id='1';这种代表查询的是字符

  假如是双引号是这样,假如你有个表的字段叫sysdate,因为sysdate属于oracle中的特有字符,但你要查询这个字段的时候

  select "sysdate" from table_name;

  但是你要是用

  select 'sysdate' from table_name;

  那么你查出来的就是字符串,结果是sysdate

  运用如下的更新语句不可以:update device set dept='select * from message where name='tom' ' ;

  处理要领:

  update device set dept='select * from message where name=' 'tom' ' where id=3' ;

  执行成功。

  原来,两个'' 示意了一个'

单引号在 Oracle 中有三种身份:

      1. 用来引用一个字符串常量,也就是界定一个字符串的开始和结束
      2. 转义符,对紧随其后出现的字符(单引号)进行转义
      3. 表示它本身,也就是它作为一个字符串的一部分而出现在一个字符串常量中

当具有不同身份的单引号紧挨着一起出现在 sql 语句中时常常令人迷惑不解,下面我将以自己总结出来的经验为基础,结合具体实例来告诉大家如何弄清每个单引号的含义。

总结经验:
1. 出现在表达式开头和结尾的这两个单引号的含义肯定是表示引用一个字符串,界定字符串的开始和结束
2. 如果单引号出现在表达式中间(即非表达式开头和结尾的单引号),且多个单引号之间没有任何其他字符,那么当我们从左向右分析时,第一对单引号中的第一个是转义符,它对紧随其后的第二个单引号进行转义,以使第二个单引号作为一个字符出现在一个字符串常量中。第二队,第三队,以此类推......

下面用实例来验证自己的经验总结:

示例一:

select '''' from dual;

result '

上图中,表达式 '''' 中第1、4个单引号表示引用一个字符串常量,表达式的剩余部分我们从左往右分析,由于中间是一对单引号,故此对中的第一个是转义符,其对第二个进行转义,使第二个表示单引号本身。分析得出这里有一个字符串常量,其中只有一个单引号字符。sql 语句的运行结果与我们的分析结果一致。

示例二:

select 'exit''''' from dual

result exit''

上图中,表达式 'exit''''' 中第一个和最后一个单引号表示引用一个字符串常量,表达式的剩余部分我们依然从左往右分析。剩余部分中,遇到的第一个单引号后面紧随一个单引号,我们将其作为一对,根据示例一,这一对的解析结果为一个单引号字符本身;然后继续向右走,又遇到一对紧挨着的单引号,同理,他们的解析结果也是一个单引号字符本身。分析得出这里的字符串常量包含exit和两个单引号字符。sql 语句的运行结果与我们的分析结果一致。


--更详细篇:

一般情况下,我们使用单引号居多
       但在字符集不一致的时候,双引号和单引号区别还是很大的
       而且,使用ODBC桥导入外部数据的时候,表名是带双引号的
      
       先看个案例:
       以前遇到过一个这样的问题
       一个朋友在创建表时,表名采用小写,并且表名用双引号括了起来
       表已经创建了,但是在查询的时候,显示表名不存在,可在user_tables又能看到这张表
       观察得出,加了双引号的小写表名存入数据库后也是小写
       用双引号扩起来的标识符都作为原来的大小写格式存放在数据字典中
       而Oracle在调用时,默认的使用大写格式去数据字典中查询
       以列名为例:

复制内容到剪贴板
代码:
sys@EMREP> create table test(a varchar2(10), a varchar2(10));

create table test(a varchar2(10), a varchar2(10))
                                  *
ERROR at line 1:
ORA-00957: duplicate column name
sys@EMREP> create table test("a" varchar2(10), a varchar2(10));

Table created.

sys@EMREP> SELECT table_name, column_name FROM user_tab_cols WHERE table_name = 'TEST';

TABLE_NAME                     COLUMN_NAME
------------------------------ ------------------------------
TEST                           a
TEST                           A
sys@EMREP> insert into test values ('1','1');

1 row created.

sys@EMREP> commit;

Commit complete.

sys@EMREP> select * from test;

a          A
---------- ----------
1          1
  以大写方式存在数据字典中,验证一下:
sys@EMREP> create table test_xxxx(a varchar2(1), "A" varchar2(1));
create table test_xxxx(a varchar2(1), "A" varchar2(1))
                                      *
ERROR at line 1:
ORA-00957: duplicate column name

       双引号括起来的更确切一点叫 "引证标识符"
       比如我们创建一张表,我们在写CREATE语句的时候,就算表名用小写,数据字典里存储的所有标识符还是大写的
       但是要想在数据字典里存储小写的标识符,那写CREATE语句的时候就得用双引号
       所以要标识符区分大小写,或在标识符中包含空格,或者使用保留字做标识符,就得用双引号括起来的引证标识符



       双引号:
             ① 表示其内部的字符串严格区分大小写
             ② 用于特殊字符或关键字
             ③ 不受标识符规则限制
             ④ 会被当成一个列来处理
             ⑤ 当出现在to_char的格式字符串中时,双引号有特殊的作用,就是将非法的格式符包装起来
                 避免出现ORA-01821: date format not recognized错误, to_char在处理格式字符串时,会忽略双引号

复制内容到剪贴板
代码:
sys@EMREP> select to_char(sysdate, 'hh24"小时"mi"分"ss"秒"') AS RESULT from dual;

RESULT
------------------
17小时31分30秒

       单引号:
             ① 表示字符串常量
             ② 字符串中的双引号仅仅被当作一个普通字符进行处理。此时,双引号不需要成对出现
                  例如:

复制内容到剪贴板
代码:
sys@EMREP> select 'hh24"小时""mi"分"""ss"秒"' AS RESULT from dual;

RESULT
-----------------------------
hh24"小时""mi"分"""ss"秒"

             ③ 动态SQL:
                在一对单引号包含的语句中,必须有一对相邻的单引号表示一个单引号
                两个相邻的单引号的作用,第一个是用来表示转义字符,后面一个表示真正的单引号
                单引号里要用单引号应该是两个连续的单引号,而不是双引号
                例如:

复制内容到剪贴板
代码:
select 'alter system kill session ''''|| sid||','||serial#|| '''';' from v$session

-----------------------------------------------一点说明---------------------------------------------------
Oracle的所有命令、语句、对象名及各种名称对大小不敏感只有对具体数据是敏感的所以在条件查询进行字符比较时定要区分大小写直观地说单引号里内容分大小写

---------------------------------------------------------------------------------------------------------------


怎样解决Oracle 中字段的值大小写不敏感。在MS Sql Server 中可以在数据库创建的时候设置这样的参数来控制大小写是否敏感。请问在Oracle中是否也可以这样设置? 如可以怎样设置?

回答:不能设置。
如果一定需要对大小写敏感,把表名,字段名等都用双引号引起来。
SQL> create table "test" as select * from dual;
表已创建。
SQL> select * from "test";
D
-
X
SQL> drop table "test";
表已丢弃。

--oracle 大小写敏感查询:

如何能使oracle中的查询大小写不敏感,查阅了一下oracle的官方文档.总结如下:

首先,oracle中默认排序和对比列值时是区分大小写的,这点与mysql可不一样!!! 


大小写不敏感的查询

  • 在数据库中可以通过语句:ALTER SESSION SET NLS_COMP = LINGUISTIC; 来使查询时,列的对比基于语义对比,会忽略大小写.但是,从执行计划中可以看到这样的信息"filter(NLSSORT(要查询的列,'nls_sort=''BINARY_CI''')=HEXTORAW(某数值)".这说明,更改了对比方式后,oracle会对这个列进行函数操作.意味着这个列上的索引会失效.当然解决方法也很直观,就对这个列建立函数索引即可:CREATE INDEX 索引名 ON T(NLSSORT(要索引的列名, 'NLS_SORT=BINARY_CI')); 索引建立后,再看执行计划,上述信息就变成了"access(NLSSORT(要查询的列,'nls_sort=''BINARY_CI''')=HEXTORAW(某数值)".这点要注意哦,不然可是全表扫描,很可能会死人的....
  • 我们在项目中当然不会向上面那样操作咯.我们是使用JDBC.这时可以这样操作:  connection.createStatement().execute("alter session set nls_comp=LINGUISTIC"); 这时你需要能修改session的权限.在ibatis里,可以直接调用execute执行alter语句.使用spring的JdbcTemplate时,除了直接执行这个语句外,还可以实现StatementCallback . 但是要注意,如果使用的是连接池,请注意使用完后修改回来,否则,这个session会被重复使用,后续的使用者将受此影响.
  • 而在hibernate中,一般可以通过将查询条件全部转换为大写或者小写来变相的实现这一目的.
    • 如果是HQL,使用oracle的LOWER()或UPPER()函数.例如: select ...... where LOWER(name) =   key.toLowerCase();
    • 如果是使用Criteria,则可以直接使用ignoreCase()或ilike()方法(注意,这个方法在like前面多了个i).例如:  
      • Restrictions.eq('colname','value′).ignoreCase()
      • Restrictions.ilike('colname','value′)
      • Restrictions.like('colname','value′).ignoreCase().
      • 这里要注意索引的问题了,有必要的话,需要建立函数索引.

大小写不敏感的排序

  • 在数据库中可以通过语句:ALTER SESSION SET NLS_SORT = BINARY_CI;索引方面同上.
  • 在项目中使用同上.

以上alter session的方式都可以改为alter system的方式对全部session生效.但是务必要注意性能问题.尤其是不敏感大小写后,oracle实际增加了函数操作,导致索引无效的问题



0 0
原创粉丝点击