1. ORACLE的SQL书写规范
/**
ORACLE的SQL规范,目的避免SQL执行错误,提高SQL脚本的质量;
一般执行SQL在command模式下,所以每个完整的语句需要在后面加上斜杠("/"),特别是过程或函数必须在其后加上斜杠("/")
多条非过程SQL语句在最后面一条语句后加上斜杠("/"),如insert、update、delete。在执行完,做下commit;
例子以表名TEST1说明,注意:create_str使用的varchar2类型,长度5000,如果SQL太长,要调整长度。
*/
declare
create_str varchar2(5000) := 'create table TEST1(ID int,REALNAME varchar2(32))';
count_flag number;
begin
select count(*)
into count_flag
from user_tables
where table_name = 'TEST1';
if count_flag < 1 then
execute immediate create_str;
else
execute immediate 'drop table TEST1';
execute immediate create_str;
--字段注解规范
execute immediate 'COMMENT ON COLUMN "TEST1"."ID" IS ''编号''';
execute immediate 'COMMENT ON COLUMN "TEST1"."REALNAME" IS ''姓名''';
end if;
end;
/
declare
add_str varchar2(5000) := 'alter table TEST1 add NICKNAME varchar(32)';
count_flag number;
begin
select count(*)
into count_flag
from user_tab_columns
where table_name = 'TEST1'
and column_name = 'NICKNAME';
if count_flag < 1 then
execute immediate add_str;
--字段注解规范
execute immediate 'COMMENT ON COLUMN "TEST1"."NICKNAME" IS ''昵称''';
end if;
end;
/
declare
add_str varchar2(5000) := 'alter table TEST1 modify NICKNAME varchar(100)';
count_flag number;
begin
select count(*)
into count_flag
from user_tab_columns
where table_name = 'TEST1'
and column_name = 'NICKNAME';
if count_flag = 1 then
execute immediate add_str;
--字段注解规范
execute immediate 'COMMENT ON COLUMN "TEST1"."NICKNAME" IS ''昵称''';
end if;
end;
/
declare
add_str varchar2(5000) := 'alter table TEST1 drop column NICKNAME';
count_flag number;
begin
select count(*)
into count_flag
from user_tab_columns
where table_name = 'TEST1'
and column_name = 'NICKNAME';
if count_flag = 1 then
execute immediate add_str;
end if;
end;
/
declare
create_str varchar2(5000) := 'create index IDX_TEST1_ID on TEST1(id)';
count_flag number;
begin
select count(*) into count_flag from user_indexes where table_name='TEST1' and index_name='IDX_TEST1_ID';
if count_flag < 1 then
execute immediate create_str;
else
execute immediate 'drop index IDX_TEST1_ID';
execute immediate create_str;
end if;
end;
/
declare
create_str varchar2(5000) := 'create sequence SEQ_TEST1 minvalue 1 maxvalue 999999999999 start with 1 increment by 1';
count_flag number;
begin
select count(*) into count_flag from user_sequences where sequence_name='SEQ_TEST1';
if count_flag < 1 then
execute immediate create_str;
else
execute immediate 'drop sequence SEQ_TEST1';
execute immediate create_str;
end if;
end;
/
insert into TEST1
(id, realname, nickname)
select 1, '网名', '网虫'
from al
where not exists (select * from TEST1 where id = 1);
/
update TEST1 set realname='网名', nickname='网虫' where id=1;
/
delete from TEST1 t where t.id=1;
/
2. 如何书写高效的SQL语句
优化SQL查询:如何写出高性能SQL语句
1、首先要搞明白什么叫执行计划?
执行计划是数据库根据SQL语句和相关表的统计信息作出的一个查询方案,这个方案是由查询优化器自动分析产生欀如一条SQL语句如果用来从一个10万条记录的表中查1条记录,那查询优化器会选择“索引查找”方式,如果该表进行了归档,当前只剩下5000条记录了,那查询优化器就会改变方案,采用 “全表扫描”方式。
可见,执行计划并不是固定的,它是“个性化的”。产生一个正确的“执行计划”有两点很重要:
(1) SQL语句是否清晰地告诉查询优化器它想干什么?
(2) 查询优化器得到的数据库统计信息是否是最新的、正确的?
2、统一SQL语句的写法
对于以下两句SQL语句,程序员认为是相同的,数据库查询优化器认为是不同的。
select * from al
select * From al
其实就是大小写不同,查询分析器就认为是两句不同的SQL语句,必须进行两次解析。生成2个执行计划。
所以作为程序员,应该保证相同的查询语句在任何地方都一致,多一个空格都不行!
3、不要把SQL语句写得太复杂
我经常看到,从数据库中捕捉到的一条SQL语句打印出来有2张A4纸这么长。一般来说这么复杂的语句通常都是有问题的。我拿着这2页长的SQL语句去请教原作者,结果他说时间太长,他一时也看不懂了。可想而知,连原作者都有可能看糊涂的SQL语句,数据库也一样会看糊涂。
一般,将一个Select语句的结果作为子集,然后从该子集中再进行查询,这种一层嵌套语句还是比较常见的,但是根据经验,超过3层嵌套,查询优化器就很容易给出错误的执行计划。因为它被绕晕了。像这种类似人工智能的东西,终究比人的分辨力要差些,如果人都看晕了,我可以保证数据库也会晕的。
另外,执行计划是可以被重用的,越简单的SQL语句被重用的可能性越高。而复杂的SQL语句只要有一个字符发生变化就必须重新解析,然后再把这一大堆垃圾塞在内存里。可想而知,数据库的效率会何等低下。
4、使用“临时表”暂存中间结果
简化SQL语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在tempdb中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。