好记性不如烂笔头,很多书看过就忘,需要用到的时候想找又找不到,既然学习了就记录一下学习要点吧,希望对以后有用。
<一>关于NULL和CHAR –对应书本第四章(神秘的NULL)和令人讨厌的CHAR
(1)B-Tree索引不存储全为null的列(B-Tree聚簇索引可以储存全为null的列) 。
ps:可以理解为全为null值的列可以在表里存在,但是不会出存储在索引里面,写SQL时若限定条件为null则查询不走索引。
(2)在DDL建表中需要注意一些细节的null问题,比如修改列默认值是null,会影响后来插入的数据,再比如新增一列有默认值,会影响前面所有插入的数据。
(3)PL/SQL中char最大字节为32767,SQL中的char则是4000。
<二>第五章——报表开发之扩展group by
(1)Oracle中的merge 语句应该保证 on 中条件的唯一性。一般而言,若merge语句的关联字段互相有主键,merge的效率将比较高。
merge into t1
using t2
on ( t1.ord_code = t2.ord_code )
when matched then
update set t1.amount = t2.amount - t2.prefential
;
(2)rollup/cube/grouping sets
grouping/grouping_id/group_id
ⅰ、rollup后面指定的列以逗号分隔,rollup的计算结果与其后面指定列的顺序有关,因为rollup分组过程具有方向性,先计算标准分组,然后列从右到左递减计算更高一级的小计,一直到列全部被选定,最后计算合计。若rollup中指定n列,则整个计算过程中分组方式有n+1种。
ⅱ、cube分组就是先进行合计,然后小计,最后全取(标准分组)。和rollup不同,cube计算结果和列的顺序无关。若cube中指定n列,则整个计算过程中分组方式有2ⁿ种。
ⅲ、grouping sets 分组只有指定某些维度的小计,而没有常规分组结果及合计结果,只对关注某些维度小计的分析很有用。grouping sets 的结果和列的顺序无关,而且结果也是无序的。n列的grouping sets的分组方式有n种。
ⅳ、grouping函数对于是小计或合计的列返回1,否则返回0。
ⅴ、grouping_id可以接受多个参数,这些参数来源于rollup/cube/grouping sets 中的列,按列从左到右顺序计算,如果此列是分组列则为0,如果是对此列的小计或合计为1,然后按列顺序将计算结果组成二进制列(位向量),最后将位向量转为十进制数。
ⅵ、group_id可以区分重复分组结果,第一次出现为0,以后每次出现增加1。常用于having中达到过滤重复统计的目的。
<三>第六章——探索Oracle自动类型转换
(1)自动类型转换规则:
①在insert 和update语句中,Oracle将赋值的类型转为目标列的类型。
②在select中,Oracle会将查询到的列的数据类型自动转为目标变量的类型。
③对数据类型的操作,Oracle经常调整其精度(precision)和刻度(scale),从而允许最大容量,在这种情况下经常看到的结果类型和表中存储的类型不一样(指精度和刻度不一样)。
④当比较字符与数值时,数值会有更高的优先级,也就是将字符转为数值进行比较。
⑤在字符类型(可转为数值的字符)、number类型与浮点类型转换,可能会丢失精度,因为数值类型和number是以十进制表示数字的,而浮点类型是以二进制表示的。
⑥将clob转为字符类型(如varchar2),或将clob转为raw类型的时候,如果被转换的类型长度比目标长度长,那么会出错。
⑦binary_float自动转为binary_double是准确的,反之,binary_double自动转为binary_float可能就不准确了。注意数值类型之间的优先级顺序:binary_double>binary_float>number,比如目标是binary_float,赋值的是number,则会转为binary_float类型。
⑧当字符串与date类型比较,date类型具有较高的优先级,将字符串转为date类型,这种自动转换需要上下文的支持。
⑨当使用SQL函数或操作符的时候,如果传入的类型和实际应该接受的类型不一致,那么会将传入的类型根据具体需要转为一致。
⑩当做赋值操作(=)的时候,Oracle会将右边被赋值的类型自动转为和左边类型一致的类型。和第②条说的select语句的赋值类似。注意这里说的赋值操作不是where column = yy 中的 = (where条件中的=是比较操作,按比较操作规则),而是说赋值给变量或列,比如update、pl/sql中的赋值操作。
⑪在做连接操作的时候,Oracle会将非字符类型转换为字符类型。
⑫在字符和非字符的算术和比较操作中,Oracle会将字符转为日期、rowid、数值类型。算术操作一般都要转为数值类型,和rowid比较如where rowid = ‘…’,要将字符转为rowid,和日期比较如where data_column = ‘…’,会将字符串根据nls参数设置转为日期类型。
⑬字符类型之间的类型转换:char/varchar2/nchar/nvarchar2。nchar和nvarchar2需要国家字符集的支持,而且是按字符存储的,char和varchar2受数据库默认字符集的支持。数据库字符集支持的char/varchar2默认转换到nchar/nvarchar2。
⑭很多SQL字符函数可以接受clob类型(比如substr/instr等都能接受clob类型),对不接受clob类型的会自动转为字符类型。对参数要求是varchar2或char,但是不允许clob类型的,如果传入clob类型也是可以的,但是有最大长度限制,只能最大4000字节,否则报错。另外有些函数比如lpad/rpad等,如果上下文是char或varchar2,也最多只能取4000字节。
⑮上面很多规则说的都是SQL中的规则,那么在pl/sql中也会存在类似的规则,只需要注意SQL和pl/sql的区别即可,比如SQL中的varchar2最大4000字节,在pl/sql中最大为32767字节。