1、概述
库级大小写是否敏感影响
(1)标识符
大小写敏感的库中,小写的标识符应使用 "" 括起,就可以区分大小写,意味着你可以创建相同名称不同大小写的表、索引等对象,或者在一张表中拥有不同大小写的列名。
大小写不敏感的库中,以上操作就不允许了,标识符被双引号括起不会使数据库区分大小写。
(2)数据库用户密码
在达梦中,用户管理相关功能并不受大小写是否敏感参数的影响。用户名会始终强转为大写,无论有没有使用双引号包裹,CREATE USER、ALTER USER 均如此,而密码始终区分大小写。
(3)模式管理
在大小写敏感的库中可拥有两个同名不同大小写的模式,这两个模式需要属于同一个用户。
在大小写不敏感的库中就只可以拥有大写的模式名。
(4)数据管理
在大小写敏感的库中,数据存储及数据比较区分大小写。
在大小写不敏感的库中,数据存储本身仍是保持原有的大小写,但是比较的时候默认不区分。
2、检查数据库实例大小写敏感信息
SELECT SF_GET_CASE_SENSITIVE_FLAG();
--1 为大小写敏感,0 为大小写不敏感
3、初始化数据库实例为大小写敏感库
1、ddl 操作
create table test3(ID int,name char(20));
select dbms_metadata.get_ddl('TABLE','test3','SYSDBA')from dual;
--未找到对象或不允许查询系统定义的内部索引
select dbms_metadata.get_ddl('TABLE','TEST3','SYSDBA')from dual;
结果如下:
/*
CREATE TABLE "SYSDBA"."TEST3"
(
"ID" INT,
"NAME" CHAR(20)) STORAGE(ON "MAIN",CLUSTERBTR);
*/
create table test6(id int,"name" chat(20));
select dbms_metadata.get_ddl('TABLE','TEST6','SYSDBA') from dual;
/*
CREATE TABLE "SYSDBA"."TEST6"
(
"ID" INT,
"name" CHAR(20)) STORAGE(ON "MAIN",CLUSTERBTR;
*/
create table "test1"(id int);
create table test1("id" int);
create table test2("id" int,id int);
select dbms_metadata.get_ddl('TABLE','test1','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."test1"
(
"ID" INT) STORAGE(ON "MAIN",CLUSTERBTR);
*/
select dbms_metadata.get_ddl('TABLE','TEST1','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."TEST1"
(
"id" INT) STORAGE(ON "MAIN",CLUSTERBTR);
*/
select dbms_metadata.get_ddl('TABLE','TEST2','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."TEST2"
(
"id" INT,
"id" INT) STORAGE(ON "MAIN",CLUSTERBTR);
*/
2、ddl操作总结
大小写敏感的数据库中,创建表时:
- 如果不对表名或列名添加"",那么表名和列名都自动转换为大写形式;
- 如果对表名或列名添加"",会固定书写时的大、小写形式,书写时采取的是小写形式,那么就定型为小写形式,其他不添加""的则自动转换为大写形式,无论书写时采取的是大写形式或小写形式。
- 同名的数据库对象,如果大小写不同,那么则为两个不同的对象,字段同样如此;
- 一个表中,即使是相同的字段名,只要大小写不同,允许存在同名且不同大小写形式的字段。
3、 其他操作
drop table test1;
create table test1(id int,name char(20));
--导出元数据
select dbms_metadata.get_ddl('TABLE','TEST1','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."TEST1"
(
"ID" INT,
"NAME" CHAR(20)) STORAGE(ON "MAIN",CLUSTERBTR);
*/
--进行 DML 操作
insert into sysdba.test1 values(1,'an');
update sysdba.test1 set id=100 where id=1;
delete from sysdba.test1 where id=100;
commit;
--4 条语句执行成功
insert into sysdba.test1("id","name") values(1,'an');
--无效的列名[id]
update sysdba.test1 set id=100 where "id"=1;
--无效的列名[id]
delete from sysdba.test1 where "id"=100;
--无效的列名[id]
4、总结
大小写敏感的数据库中,DML 或 DDL 操作时:
- 如果不对表名或列名添加"",那么表名和列名都自动转换为大写形式;
-
- 对表进行 DML 操作时,如果没有小写形式的字段,不能采取小写加""的形式指定过滤字段,会被认定为无效的字段;
- 如果对表名或列名添加"“,会固定书写时的大、小写形式,""中是大写形式,则过滤字段就是大写字段,”"中是小写字段,则过滤字段就是小写字段;
- 对其进行 DML 操作时,需要利用""指定表名和字段名,否则默认会认定以大写形式去查询对象。
- 查询时,''和""界定符中字符串区分大小写,界定符中的字符串若是大写形式,那仅查询这个大写形式的对象,若是或小写形式,那仅查询这个小写形式的对象,DML 操作依旧。
4、 数据库为大小写不敏感库
1、ddl 操作
create table test3(ID int,name char(20));
select dbms_metadata.get_ddl('TABLE','test3','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."test3"(
"ID" INT,"name" CHAR(20)) STORAGE(ON "MAIN",CLUSTERBTR);
*/
select dbms_metadata.get_ddl('TABLE','TEST3','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."test3"(
"ID" INT,
"name" CHAR(20)) STORAGE(ON "MAIN",CLUSTERBTR);
*/
create table test6(id int,"name" char(20));
select dbms_metadata.get_ddl('TABLE','TEST6','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."test3"("id" INT,"name" CHAR(20))
STORAGE(ON "MAIN",CLUSTERBTR);
*/
create table "test1"(id int);
--执行成功
create table test1("id" int);
--执行失败 对象[test1]已存在
create table TEST1("id" int);
--对象[test1]已存在
create table test2("id" int,id int);
--执行失败 列[id]已存在
select dbms_metadata.get_ddl('TABLE','test1','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."test1"
(
"id" INT) STORAGE(ON "MAIN", CLUSTERBTR);
*/
select dbms_metadata.get_ddl('TABLE','TEST1','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."test1"
(
"id" INT) STORAGE(ON "MAIN", CLUSTERBTR);
*/
2、ddl操作总结
大小写不敏感的数据库中,创建表时:
- 无论对不对表名或列名添加"",表名和列名的大小写形式不会发生变化,大写形式就是大写形式,小写形式就是小写形式;
- 不允许存在同名的数据库对象,即使大小写不同,默认也只能存在一个;
- 一个表中,也不允许相同的字段名,即使大小写不同;
- 查询时,''和""界定符不区分大小写,界定符中的查询或过滤条件即使是大写或小写,都可以查询到预期的结果集。
3、其他操作
drop table test1;
create table test1(id int,name char(20));
--导出元数据
select dbms_metadata.get_ddl('TABLE','TEST1','SYSDBA')from dual;
/*
CREATE TABLE "SYSDBA"."test1"
(
"id" INT,
"name" CHAR(20)) STORAGE(ON "MAIN", CLUSTERBTR);
*/
--进行 DML 操作
insert into sysdba.test1 values(1,'an');
update sysdba.test1 set id=100 ehere id=1;
delete from sysdba.test1 where id=100;
commit;
--4 条语句执行成功
insert into sysdba.test1("id","name") values(1,'an');
--执行成功
update sysdba.test1 set id=100 where ID=1;
--执行成功
select * from TEST1 where NAME='AN';
/*
id name
100 an
*/
delete from sysdba.test1 where NAME='AN';
--执行成功
select * from TEST1;
-null
4、总结
大小写不敏感的数据库中,DML 或 DDL 操作时:
- 无论对不对表名或列名添加"",表名和列名的大小写形式不会发生变化,大写形式就是大写形式,小写形式就是小写形式;
- 不允许存在同名的数据库对象,即使大小写不同,默认也只能存在一个;
- 一个表中,也不允许相同的字段名,即使大小写不同;
- 查询时,''和""界定符不区分大小写,界定符中的查询或过滤条件即使是大写或小写,都可以查询到预期的结果集,进行 DML 操作时依旧。
5、BINARY 前缀
数据库是否大小写敏感通过建库参数 CASE_SENSITIVE 控制,初始化后便无法修改,可以通过系统函数 SF_GET_CASE_SENSITIVE_FLAG()或 CASE_SENSITIVE()查询设置的参数值。为了便于用户在数据库初始化后依旧可以按需求进行局部大小写敏感的字符比较操作,提供 BINARY 前缀方式用于设置表达式比较时为大小写敏感。字符的局部大小写敏感还可以通过设置会话属性进行。
1、BINARY 前缀支持范围:
- SQL 项:查询项、过滤条件、连接条件、层次查询条件、having 条件、排序项、分组项。
- 表达式类型:逻辑比较表达式、模糊查询表达式(包括 row like)、查询表达式(例如:in、逻辑比较,但不支持多列 in、多列逻辑比较)等。
BINARY 前缀在顶层查询项的含义是将查询项转换为原始值字符串 ASCII 码的十六进制形式,例如:将 123abc 转换为 0x313233616263;在除顶层查询项外的其他位置则表示该前缀修饰的表达式将按照大小写敏感进行比较,无论当前数据库为大小写敏感或不敏感。
例 在顶层查询中添加 BINARY 前缀与在子查询中添加 BINARY 前缀。
CREATE TABLE BT(C1 VARCHAR, C2 VARCHAR, C3 VARCHAR);
INSERT INTO BT VALUES('AaBbCc','a','A');
INSERT INTO BT VALUES('KkKkKk','B','b');
INSERT INTO BT VALUES('A','b','C');
INSERT INTO BT VALUES('avcs','A','b');
在顶层查询中添加 BINARY 前缀。
SELECT BINARY C1 FROM BT;
查询结果如下
行号 BINARY C1
---------- --------------
1 0x416142624363
2 0x4B6B4B6B4B6B
3 0x41
4 0x61766373
在子查询中添加 BINARY 前缀。
SELECT * FROM (SELECT BINARY C1 FROM BT);
查询结果如下:
行号 C1
---------- ------
1 AaBbCc
2 KkKkKk
3 A
4 avcs
在条件查询的子查询中添加 BINARY 前缀。
SELECT C1 FROM BT WHERE C1 = (SELECT TOP 1 BINARY C1 FROM BT);
行号 C1
---------- ------
1 AaBbCc
BINARY 前缀位于过滤条件、连接条件、HAVING 条件或层次查询条件中的表达式之前时,该表达式在比较时按照大小写敏感比较,且 BINARY 前缀只对当前 and/or 子句生效。例如:在表达式 c1 = 'a' and binary c2 = 'b' and c3 = 'c'中只有第二个条件一定按照大小写敏感比较,其它两个条件仍按照数据库参数是否大小写敏感比较。
例 1 在数据库初始化为大小写不敏感的情况下(即参数 CASE_SENSITIVE=0),执行查询语句,其中只有一条 and 子句添加 BINARY 前缀。
SELECT C1,C2,C3 FROM BT WHERE C1 = 'a' AND BINARY C2 = 'b' AND C3 = 'c';
查询结果如下:
行号 C1 C2 C3
---------- -- -- --
1 A b C
例 2 在数据库初始化为大小写敏感的情况下(即参数 CASE_SENSITIVE=1),执行查询语句,其中只有一条 and 子句添加 BINARY 前缀。
SELECT C1,C2,C3 FROM BT WHERE C1 = 'a' AND BINARY C2 = 'b' AND C3 = 'c';
查询结果如下: 未选定行
BINARY 前缀位于排序项或分组项中的表达式之前时,该表达式按照大小写敏感进行排序/分组,若存在多个排序项/分组项,则仅有含有 BINARY 前缀的项生效,其余项仍按照数据库参数是否大小写敏感进行排序/分组
例 在数据库初始化为大小写不敏感的情况下,对排序项中不添加 BINARY 前缀与添加 BINARY 前缀进行对比。
排序项中不添加 BINARY 前缀。
SELECT C1,C2,C3 FROM BT ORDER BY C2;
查询结果如下:
行号 C1 C2 C3
---------- ------ -- --
1 AaBbCc a A
2 avcs A b
3 A b C
4 KkKkKk B b
对排序项中添加 BINARY 前缀。
SELECT C1,C2,C3 FROM BT ORDER BY BINARY C2;
查询结果如下:
行号 C1 C2 C3
---------- ------ -- --
1 avcs A b
2 KkKkKk B b
3 AaBbCc a A
4 A b C
使用说明
- 仅对字符类型生效,其他数据类型忽略 BINARY 前缀。
- 多列比较不支持 BINARY 前缀,例如多列逻辑比较,多列 IN LIST 等。
- 创建索引时忽略 BIANRY 前缀。
- 确定性函数参数忽略 BINARY 前缀。
- CONTAINS 表达式忽略 BINARY 前缀。
- ALL/SOME/ANY 子查询忽略 BINARY 前缀。
- 层次查询表达式忽略 BINARY 前缀。
- 集函数参数包括 WITHIN GROUP 中排序表达式忽略 BINARY 前缀。
- 分析函数参数包括 OVER 中的排序表达式、分组表达式忽略 BINARY 前缀。