q可以把个别的select命o用圆括号Q这P可以Ҏơ查询以及最l结果做出limit和order by 讄?/p>
(select * from tbl1 order by colA limit 10) union (select * from tbl2 order by colA limit 10) order by
coltimestamp limit 5
SELECT * FROM order_master WHERE vencode = 'V002'
FOR UPDATE WAIT 5;
UPDATE .....
COMMIT;
LOCK TABLE <table_name> IN <look_mode> MODE [NOWAIT];
?行共享(ROW SHARE, RSQ?br /> ?行排他(ROW EXCLUSIVE, RXQ?br /> ?׃nQSHARE, SQ?br /> ?׃n行排他(SHARE ROW EXCLUSIVE, SRXQ?br /> ?排他QEXCLUSIVE, XQ?br />
CREATE TABLE sales
(
...
)
PARTTION BY RANGE (sales_cost)
(
PARTTION P1 VALUES LESS THAN (1000),
PARTTION P2 VALUES LESS THAN (2000),
PARTTION P3 VALUES LESS THAN (3000),
PARTTION P4 VALUES LESS THAN (MAXVALUE) /* 大于3000的其他值都存储于分?P4 */
);
CREATE TABLE employer
(
...
)
PAERTTION BY HASH (department) PARTTIONS 4;
CREATE TABLE sales
(
...
)
PARTTION BY RANGE (sales_date)
SUBPARTTION BY HASH (product_id) SUBPARTTION 5
(
PARTTION P1 VALUES LESS THEN (DATE '2001-04-01'),
PARTTION P2 VALUES LESS THEN (DATE '2001-07-01'),
PARTTION P3 VALUES LESS THEN (DATE '2001-09-01'),
PARTTION P4 VALUES LESS THEN (MAXVALUE)
);
CREATE TABLE employee
(
...
)
PARTTION BY LIST (emp_address )
(
PARTTION north VALUES ('芝加?),
PARTTION west VALUES ('旧金?, 'z杉?),
PARTTION south VALUES ('亚特兰大', '达拉?, '休斯?),
PARTTION east VALUES ('U约' ,'波士?),
PARTTION aa VALUES (DEFAULT) /* 其他的地址存储 aa 分区Q不指定则不接受其他地址输入 */
);
CREATE OR REPLACE VIEW myview
AS
SELECT * FROM books WHERE price>30
WITH CHECK OPTION;
/* 当利用视图插入一?price<=30 的数据时会报?*/
?公有同义词:DBA建立Q所有用户共同拥有。CREATE PUBLIC SYNONYM ...DESC user_synonyms;
?U有同义词:用户建立Q用与该用P对象Q可被授权)?br />
CREATE OR REPLACE SYNONYM dept FOR scott.dept;
SELECT * FROM dept;
CREATE SEQUENCE sequence_name
[START WITH integer] /* 序列起始|升序默认为最|降序默认为最大?*/
[INCREMENT BY integer] /* 递增量,默认?1Q?*/
[MAXVALUE integer | NOMAXVALUE] /* 最大|默认?NOMAXVALUE */
[MINVALUE integer | NOMINVALUE] /* 最|必须于{于起始值和 于最大?*/
[CYCLE | NOCYCLE] /* 序列到达最大值后是否循环Q默认ؓ NOCYCLE 不@?*/
[CACHE integer | NOCACHE]; /* 是否预分配序列号Q默认缓?0个序列号 */
例:两表U联更新Q修攚w门表~号的同时也修改员工表的部门~号Q?br /> CREATE OR REPLACE TRIGGER update_dept
/* 行触发器,在更新部门表操作后触?*/
AFTER UPDATE ON deptment
FOR EACH ROW
BEGIN
/* new、old 表的有效利用Q把旧表的id列?更新?新表的id列?*/
UPDATE emp SET id=:new.id WHERE id=:old.id;
END;
UPDATE deptment SET id='yy' WHERE id='01';
SELECT * FROM deptment;
SELECT * FROM emp;
插入时利用触发器+序列实现整型字段的自增:
CREATE OR REPLACE TRIGGER set_no
BEFORE INSERT ON auto
FOR EACH ROW
DECLARE
sn number(5);
BEGIN
/* 触发器预处理序列的?*/
SELECT myseq.nextval INTO sn FROM dual;
:NEW.a := sn;
END;
INSERT INTO auto VALUES(21,'dtt');
SELECT * FROM auto;
/* 插入时表a列由触发器生的值替代用L输入 */
例如Q利用触发器记录Q记录某表中用户的操作(日志处理Q?br /> CREATE OR REPLACE TRIGGER dm1_aaps.能否记录多个表?"after insert or delete or update on t1,t2" 出错?br />
AFTER INSERT OR DELETE OR UPDATE ON aa
BEGIN
IF INSERTING THEN
INSERT INTO mylog VALUES(user,sysdate,'I');
ELSEIF DELETING THEN
INSERT INTO mylog VALUES(user,sysdate,'D');
ELSE
INSERT INTO mylog VALUES(user,sysdate,'U');
END IF;
END;
例如Q在视图中插入新的部门同时插入其所属的新员工:
CREATE OF REPLACE TRIGGER tr_v_e_d
/* 在视图上创徏替换触发?*/
INSTEAD OF INSERT ON v_emp_dept
FOR EACH ROW
BEGIN
/* 替换触发器先插入部门表的信息Q然后再插入其所属员工表的信?*/
INSERT INTO deptment VALUES(:new.id, :new.name);
INSERT INTO emp(eid, ename, sex, id) VALUES(:new.eid, :new.ename, :new.sex, :new.d);
END;
INSERT INTO v_emp_dept VALUES('456', 'test', 'f', '33', 'hg');
SELECT * FROM v_emp_dept;
例如Q对用户所删除的所有对象进行日志记?br /> CREATE OR REPLACE TRIGGER log_drop_obj
AFTER DROP ON SCHEMA
BEGIN
/* 记录操作cd、操作对象、操作时?*/
INSERT INTO dropped_obj VALUES(ORA_DICT_OBJ_NAME, ORA_DICT_TYPE, SYSDATE);
END;
CREATE TABLE for_drop(x char);
DROP TABLE for_drop;
SELECT * FROM dropped_obj;
CREATE OR REPLACE TRIGGER system_startup
AFTER STARTUP ON DATABASE
BEGIN
...
END;
SET SERVEROUTPUT ON;
DECLARE
CURSOR cur IS
SELECT * FROM books;
myrecord books%ROWTYPE;
BEGIN
OPEN cur;
LOOP
FETCH cur INTO books;
EXIT WHEN cur%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(books.id || ' ' || books.name);
END LOOP;
CLOSE cur;
END;
DECLARE1.3、用显C游标删除或更新记录
/* 定义带参数游?*/
CURSOR cur_para(id varchar2) IS
SELECT books_name FROM books WHERE books_id = id;
BGEIN
/* 调用带参数游标,q以 FOR 循环方式处理 */
FOR cur IN cur_para('0001') LOOP
DBMS_OUTPUT.PUT_LINE(cur.books_id || ' ' || cur.books_id);
END LOOP;
END;
BEGIN
FROM cur IN (SELECT name FROM deptment) LOOP
DBMS_OUTPUT.PUT_LINE(cur.books_id || ' ' || cur.books_id);
END LOOP;
END;
CREATE OR REPLACE PROCEDURE test (value IN varchar2, value2 OUT NUMBER)
/* 参数Q不需指定长度或精?*/
IS
/* 局部变量,省略 DECLARE 关键字,需有长?*/
identity NUMBER;
BEGIN
SELECT ITEMRATE INTO identity
FROM itemFile
WHERE itemcode = value;
IF identity < 200 THEN
value2 := 200;
ELSE
value2 :=50;
END IF;
END;
DECLARE?单独执行
tvalue2 NUMBER;
BEGIN
test('i202', tvalue2);
DBMS_OUTPUT.PUT_LINE('value2的gؓQ? || TO_CHAR(value2));
END;
CREATE OR REPLACE FUNCTION item_price_rage (price NUMBER)
/* 参数、指定返回类?*/
RETURN varchar2
AS
/* 定义局部变?*/
min_price NUMBER;
max_price NUMBER;
BEGIN
SELECT MAX(ITEMRATE), MIN(ITEMRATE) INTO max_price, min_price
FROM itemfile;
IF price >= min_price AND price <= max_price THEN
RETURN '输入的单价介于最低h与最高h之间';
ELSE
RETURN '出范围';
END IF;
END;
DECLARE?SELECT查询调用Q因为函数必Lq回|
p NUMBER := 300;
MSG varchar2(200);
BEGIN
MSG := item_price_range(p);
DBMS_OUTPUT.PUT_LINE(MSG);
END;
CREATE OR REPLACE PACKAGE pack_me*创徏 pack_me 包,q声明了子程?order_proc ?order_funQƈ交由E序包主体实现?br />
IS
PROCEDURE order_proc (orno varchar2);
FUNCTION order_fun (ornos varchar2) RETURN varchar2;
END pack_me;
CREATE OR REPLACE PACKAGE BODY pack_me
AS
/* 实现定义的存储过E?*/
PROCEDURE order_proc (orno varchar2)
IS
stst CHAR(1);
BEGIN
SELECT ostatus INTO stat FROM order_master
WHERE orderno = orno;
IF stat = 'p' THEN
DBMS_OUTPUT.PUT_LINE('暂挂的订?);
ELSE
DBMS_OUTPUT.PUT_LINE('已完成的订单');
END IF;
END order_proc;
/* 实现定义的函?*/
FUNCTION order_fun(ornos varchar2) RETURN varchar2
IS
icode varchar2(5);
ocode varchar2(5);
qtyord NUMBER;
qtydeld NUMBER;
BEGIN
SELECT qty_ord, qty_deld, itemcode, ordernc INTO qtyord, qtydeld, icode, ocode
FROM order_detail
WHERE orderno = ornos;
IF qtyord < qtydeld THEN
RETURN ocode;
ELSE
RETURN icode;
END IF;
END order_fun;
END pack_me;
DECLARE
msg varchar2(10);
BEGIN
msg := pack_me.order_fun('o002');
DBMS_OUTPUT.PUT_LINE('值是 ' || msg);
END;
DECLARE变量声明内容Q赋予变量适当的名U、数据类型、定义变量(标准Q记录)、控制变量范围?br /> 变量命名规则Q变量以字符开_可包含数字、下划线??Q长度范?1?0Q不区分大小写;不能使用pȝ关键字?br />
...
BEGIN
...
EXCEPTION
...
END;
IF ... THEN
...
ELSEIF ...THEN
...
ELSE
...
END IF;
CASE
WHEN ... THEN
...
ELSE
...
END CASE;
LOOP
...
END LOOP;
WHILE condition LOOP
...
END LOOP;
FOR counter IN [REVERSE] start..end
LOOP
...
END LOOP;
GOTO xxxx;
...
<<xxxx>>
NULL;
EXCEPTION
WHEN xxxx THEN
....
DECLARE
-- 自定义异?br /> xxxxx EXCEPTION;
BEGIN
-- 昑ּ引发异常
RAISE xxxxx
EXCEPTION
-- 异常处理
WHEN xxxxx THEN
....
END;
DECLARE
TYPE myrecord IS RECORD(id varchar2(10), name varchar2(10));
real_record myrecord;
BEGIN
-- SELECT .. INTO 赋D?br /> SELECT emp_id, emp_name INTO real_record FROM emp WHERE emp_id='001';
.....
END;
ORACLE中数据字典视囑ֈ?大类Q用前缀区别Q分别ؓQUSERQALL ?DBAQ许多数据字典视囑含相似的信息?br />
?USER_*:有关用户所拥有的对象信息,即用戯己创建的对象信息
?ALL_*Q有关用户可以访问的对象的信息,即用戯己创建的对象的信息加上其他用户创建的对象但该用户有权讉K的信?br /> ?DBA_*Q有x个数据库中对象的信息
Q这里的*可以为TABLESQ?INDEXESQ?OBJECTSQ?USERS{)
1.查看所有用P
select * from dba_user;
select * from all_users;
select * from user_users;
2.查看用户pȝ权限Q?br /> select * from dba_sys_privs;
select * from all_sys_privs;
select * from user_sys_privs;
3.查看用户对象权限Q?br /> select * from dba_tab_privs;
select * from all_tab_privs;
select * from user_tab_privs;
4.查看所有角Ԍ
select * from dba_roles;
5.查看用户所拥有的角Ԍ
select * from dba_role_privs;
select * from user_role_privs;
6.查看当前用户的缺省表I间
select username,default_tablespace from user_users;
7.查看某个角色的具体权限,如grant connect,resource,create session,create view to TEST;
查看RESOURCEh那些权限Q用SELECT * FROM DBA_SYS_PRIVS WHERE GRANTEE='RESOURCE';
模式对象/权限 | ALTER | DELETE | EXECUTE | INDEX | INSERT | READ | REFERENCE | SELECT | UPDATE |
Directory | √ | ||||||||
function | √ | ||||||||
procedure | √ | ||||||||
package | √ | ||||||||
DB Object | √ | ||||||||
Libary | √ | ||||||||
Operation | √ | ||||||||
Sequence | √ | ||||||||
Table | √ | √ | √ | √ | √ | √ | √ | ||
Type | √ | ||||||||
View | √ | √ | √ | √ |
角色名称 | 说明 |
CONNECT |
数据库连接角Ԍ用于q接数据库,h创徏、数据库链接、序列、同义词、表和视图,以及修改会话的权? |
DBA |
数据库管理员角色Q具有所有用ADMIN选项创徏的系l权限,可以系l权限授予其他用h角色 |
DELETE_CATALOG_ROLE |
删除目录角色Q可以删除或重徏数据字典 |
EXECUTE_CATALOG_ROLE |
执行目录角色Q能够执行所有系l包 |
EXP_FULL_DATABASE |
能够使用导出E序执行数据库的完全和增量导? |
IMP_FULL_DATABASE |
能够使用导入E序执行数据库的完全导入 |
RESOURCE |
可以创徏、表、序列以及PL/SQL~程用方案对象,包括q程、程序包、触发器{? |
SELECT_CATALOG_ROLE |
查询数据字典表或视图 |
定义格式 | 输入数?/td> | 存储状?/td> |
NUMBER | 123.89 | 123.89 |
NUMBER(5) | 123.89 | 124 |
NUMBER(5,0) | 123456 | ORA-01438: 值大于ؓ此列指定的允许精?/td> |
NUMBER(6,2) | 123.89 | 123.89 |
123.8951 | 123.9 | |
NUMBER(2,5) | 0.000811 | 0.00081 |
123.89 | ORA-01438: 值大于ؓ此列指定的允许精?/td> | |
1.2e-4 | 0.00012 |
1.Ҏ询进行优化,应尽量避免全表扫描,首先应考虑?where ?order by 涉及的列上徏立烦引?
2.应尽量避免在 where 子句中对字段q行 null 值判断,否则导致引擎放弃用烦引而进行全表扫描,如:
select id from t where num is null
可以在num上设|默认?Q确保表中num列没有null|然后q样查询Q?
select id from t where num=0
3.应尽量避免在 where 子句中?=?lt;>操作W,否则引擎放弃用烦引而进行全表扫描?
4.应尽量避免在 where 子句中?or 来连接条Ӟ否则导致引擎放弃用烦引而进行全表扫描,如:
select id from t where num=10 or num=20
可以q样查询Q?
select id from t where num=10
union all
select id from t where num=20
5.in ?not in 也要慎用Q否则会D全表扫描Q如Q?
select id from t where num in(1,2,3)
对于q箋的数|能用 between ׃要用 in 了:
select id from t where num between 1 and 3
6.下面的查询也导致全表扫描:
select id from t where name like '%abc%'
若要提高效率Q可以考虑全文索?
7.如果?where 子句中用参敎ͼ也会D全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将讉K计划的选择推迟到运行时Q它必须在编译时q行选择。然而,如果在编译时建立讉K计划Q变量的D是未知的Q因而无法作为烦引选择的输入项。如下面语句进行全表扫描:
select id from t where num=@num
可以改ؓ强制查询使用索引Q?
select id from t with(index(索引?) where num=@num
8.应尽量避免在 where 子句中对字段q行表达式操作,q将D引擎攑ּ使用索引而进行全表扫描。如Q?
select id from t where num/2=100
应改?
select id from t where num=100*2
9.应尽量避免在where子句中对字段q行函数操作Q这导致引擎放弃用烦引而进行全表扫描。如Q?
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
应改?
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
10.不要?where 子句中的“=”左边q行函数、算术运或其他表达式运,否则pȝ可能无法正用烦引?
11.在用烦引字D作为条件时Q如果该索引是复合烦引,那么必须使用到该索引中的W一个字D作为条件时才能保证pȝ使用该烦引,否则该烦引将不会被用,q且应尽可能的让字段序与烦引顺序相一致?
12.不要写一些没有意义的查询Q如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
q类代码不会q回Ml果集,但是会消耗系l资源的Q应Ҏq样Q?
create table #t(...)
13.很多时候用 exists 代替 in 是一个好的选择Q?
select num from a where num in(select num from b)
用下面的语句替换Q?
select num from a where exists(select 1 from b where num=a.num)
14.q不是所有烦引对查询都有效,SQL是根据表中数据来q行查询优化的,当烦引列有大量数据重复时QSQL查询可能不会d用烦引,如一表中有字DsexQmale、female几乎各一半,那么即在sex上徏了烦引也Ҏ询效率v不了作用?
15.索引q不是越多越好,索引固然可以提高相应?select 的效率,但同时也降低?insert ?update 的效率,因ؓ insert ?update 时有可能会重建烦引,所以怎样建烦引需要慎重考虑Q视具体情况而定。一个表的烦引数最好不要超q?个,若太多则应考虑一些不怋用到的列上徏的烦引是否有必要?
16.应尽可能的避免更?clustered 索引数据列,因ؓ clustered 索引数据列的序是表记录的物理存储序Q一旦该列值改变将D整个表记录的序的调_会耗费相当大的资源。若应用pȝ需要频J更?clustered 索引数据列,那么需要考虑是否应将该烦引徏?clustered 索引?
17.量使用数字型字D,若只含数g息的字段量不要设计为字W型Q这会降低查询和q接的性能Qƈ会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字W,而对于数字型而言只需要比较一ơ就够了?
18.可能的使用 varchar/nvarchar 代替 char/nchar Q因为首先变长字D存储空间小Q可以节省存储空_其次对于查询来说Q在一个相对较的字段内搜索效率显然要高些?
19.M地方都不要?select * from t Q用具体的字D列表代?#8220;*”Q不要返回用不到的Q何字Dc?
20.量使用表变量来代替临时表。如果表变量包含大量数据Q请注意索引非常有限Q只有主键烦引)?
21.避免频繁创徏和删除时表Q以减少pȝ表资源的消耗?
22.临时表ƈ不是不可使用Q适当C用它们可以某些例程更有效,例如Q当需要重复引用大型表或常用表中的某个数据集时。但是,对于一ơ性事Ӟ最好用导?
23.在新Z时表Ӟ如果一ơ性插入数据量很大Q那么可以?select into 代替 create tableQ避免造成大量 log Q以提高速度Q如果数据量不大Qؓ了缓和系l表的资源,应先create tableQ然后insert?
24.如果使用C临时表,在存储过E的最后务必将所有的临时表显式删除,?truncate table Q然?drop table Q这样可以避免系l表的较长时间锁定?
25.量避免使用游标Q因为游标的效率较差Q如果游标操作的数据过1万行Q那么就应该考虑改写?
26.使用Z游标的方法或临时表方法之前,应先LZ集的解决Ҏ来解决问题,Z集的Ҏ通常更有效?
27.与时表一P游标q不是不可用。对型数据集?FAST_FORWARD 游标通常要优于其他逐行处理ҎQ尤其是在必d用几个表才能获得所需的数据时。在l果集中包括“合计”的例E通常要比使用游标执行的速度快。如果开发时间允许,Z游标的方法和Z集的Ҏ都可以尝试一下,看哪一U方法的效果更好?
28.在所有的存储q程和触发器的开始处讄 SET NOCOUNT ON Q在l束时设|?SET NOCOUNT OFF 。无需在执行存储过E和触发器的每个语句后向客户端发?DONE_IN_PROC 消息?
29.量避免大事务操作,提高pȝq发能力?
30.量避免向客Lq回大数据量Q若数据量过大,应该考虑相应需求是否合理?