DB DAY DAY UP

 

数据库设计的实用原则是:在数据冗余和处理速度之间找到合适的平衡点.

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

Oracle中SQL语句中两个单引号之间的字符数不能大于4000.

Oracle表名称限制在30内。

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

UNION 与 UNION ALL 不同,UNION 会去掉结果集中的重复记录。

UNION因为要去掉重复的记录,会对结果集排序而用到零时表空间。

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

where与having的区别

where条件作用于分组前的每一条记录,having条件作用于分好组后的组。

SELECT<attributes and function lists>

FROM<Table list>

[WHERE <condition>

GROUP BY <grouping attributes>

HAVING <group condition>

ORDER BY<attribute list>]; 
-------------------------------------------------------------------------------------------------------------

对字段建立了索引,但不一定会被使用:
select * from emp where to_char(hire_date,'yyyymmdd')='20080411' (不使用)
select * from emp where hire_date = to_char('20080411','yyyymmdd') (使用)

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

SQL语句最好用大写,因为oracle总是先解析SQL语句,把小写的字母转换成大写的再执行。

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

子查询不但可以出现在Where子句中,也可以出现在from子句中,作为一个临时表使用,也可以出现在select list中,作为一个字段值来返回。

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

利用create schema authorization “登录用户名” 把多个DDL “限定在一个”事务“中。

在创建系统的安装脚本时,经常创建一部分表后出现错误,退出安装脚本。这个时候一般要先清除脚本,把原来创建的表先删除。如果使用Create Schema语句,当后面的语句失败了,前面的语句创建的对象或授权自动取消,就不必再执行清除操作。

CREATE SCHEMA AUTHORIZATION yorker
create table yorker.aa(id int)
create table yorker.bb (id int);

注意只在最后一句加分号,如果创建bb时候失败(如把int写成了int2),aa表也不会被创建。

目前,只有CREATE TABLE,CREATE VIEW,CREATE INDEX,CREATE SEQUENCE,CREATE TRIGGER和GRANT是在CREATE SCHEMA

里面可以接受的子句。

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

高效的删除重复记录方法,只保留一条 (使用ROWID)例子:

DELETE  FROM  BB E  WHERE  E.ROWID >
(SELECT MIN(X.ROWID) FROM  BB X  WHERE  X.ID = E.ID);

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

如何取top n记录,(使用rownum)

SELECT * FROM (SELECT id from bb order by id) where rownum <3;

如果top 3有4条记录怎么办呢?

SELECT * FROM ( SELECT test.*,RANK() OVER (ORDER BY id DESC) ranknum from test) where ranknum <3;

[这种取法只能用于取前多少条或者第一条,如第一条(=1或者<=2),前两条(<3或者<=2),不支持第二条(=2),不支持第2条到第5条的取法(rownum>=2 and rownum<=5)]

取第M条到第N条之间的

select *
  from (select id,name,row_number() over(order by id) rn
          from user) t
where t.rn>=4 and t.rn <=6

SELECT *
  FROM (SELECT ROWNUM AS rownumber, t.*
          FROM (SELECT   ID
                    FROM TEST
                ORDER BY ID) t)
 WHERE rownumber > 3 AND rownumber <= 7;

删除M条到第N条之间的记录

delete from tb1 where rowid in
(SELECT rowid  FROM (SELECT rowid,id,VAL,row_number() over (order by VAL) rn from TB1 ) 

where rn >2 and rn<6);

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

NULL值对AVG和COUNT函数的影响:

AVG会把对应字段值为NULL的行排除在外,用 AVG(ISNULL(Col,合理值:如0代替))。

COUNT(Col) 会把对应字段值为NULL的行排除在外,COUNT(*)不会,即使该行所有的列的值都为NULL。

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

如下表中,对于相同的name,取time时间最新的记录

name time1   time2 
AA 2008-2-12 2008-2-13
AA 2008-2-12 2007-2-12
BB 2007-2-12 2006-2-12
BB 2008-2-12 2007-2-12
BB 2009-2-12 2008-1-12
取到:
AA 2008-2-12 2008-2-13
BB 2009-2-12 2008-1-12
AA里面2008-2-13是最新的
BB里面2009-2-12最新

 

select * from mytable1 outtb
where time1>= (select decode(sign(MAX(time1)-MAX(time2)),-1,MAX(time2),MAX(time1)) From mytable1 innertb  where outtb.name = innertb.name group by innertb.name )
or time2>= (select decode(sign(MAX(time1)-MAX(time2)),-1,MAX(time2),MAX(time1)) From mytable1 innertb  where outtb.name = innertb.name group by innertb.name )

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

表被drop后重建,需要重建与之关联的trigger。

视图被drop后重建,也需要重建与之关联的trigger。

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

如何取字符串中的每一个字符:connect by

selectsubstr(s, rownum,1)
from (select' 12345678 ' s fromdual)
connect byrownum<= length(s);

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

 

AUTHID CURRENT_USER子句不能应用于子程序的静态调用。因为程序的静态调用是在编译时就被解释的,而不是运行时。

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

DBMS_JOB里的方法调用后,要COMMIT才生效.


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

Oracle package的spec里定义的Function,Procedure在和Body里的实现进行一致性检查的时候,是逐字符进行比较的(空白字符不计),所以,形式参数的位置,命名也必须保持一致.

Package Body里的初始化代码只在第一次装载的时候调用一次,必须放在body的最后,以begin开头,没有end关键字.

BEGIN

-- initialization part starts here

 


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

where条件中不能用SELECT中出现的别名作为字段查询,必须用表的字段的真实名称.

如: select isbn as bookid from books where bookid ='1122' 是不合法的.

但是select * from(select id as myid from t) where myid=3;是合法的.

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

动态SQL里的数据库对象(如表)不能用绑定变量的方式执行,如:

CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE ’DROP TABLE :tab’ USING table_name; --不合法
END;

数据库对象(如表)只能用连接字符串的方式组成动态SQL,如:

CREATE PROCEDURE drop_table (table_name IN VARCHAR2) AS
BEGIN
EXECUTE IMMEDIATE ’DROP TABLE ’ || table_name;
END;

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

将cursor的值fetch到用%rowtype定义的record的时候,select list的顺序必须和表的定义的字段顺序保持一致或者用

select * 来定义cursor.


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

当字段名和局部变量重名时,字段名的优先级更高,下面的例子会把emp表的数据全删掉.

DECLARE
ename VARCHAR2(10) := ’KING’;
BEGIN
DELETE FROM emp WHERE ename = ename;


一个更隐蔽的例子,tab中有val和val1字段.

DECLARE
val1 VARCHAR2(10) := 'b';
BEGIN
DELETE FROM tab WHERE val = val1;
end;



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

 

NULL and TRUE = NULL;

NULL or FALSE = NULL;

NOT NULL = NULL;

DELETE FROM emp WHERE ename NOT IN (NULL, ’KING’);不会删除任何行. NOT IN (NULL...)总是FALSE

NOT的优先级比and和or高,如 NOT valid AND done = (NOT valid) AND done


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

付给用户的role权限需要用户从新登录才起作用.

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

游标变量(ref cursor)可以用open for打开多次,而静态游标在关闭前不能再被打开.

不能在包的声明中定义游标变量,游标变量类型不能作为集合元素的类型.

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

Oracle中,在更新同一行中的A字段,在还没有提交前,不能在另一个session中更新同一条记录的B字段.

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

用一条SQL更新满足条件记录的A为X值,B在不为B特殊值的时候为Y值:

update tb set A='X', B=decode(B,'sp_b',val,'Y') where .....

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

Oracle 表的外键可以为空.


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

sys用户密码丢失,1,用orapwd重建密码文件。2,修改sqlnet.ora为操作系统认证,登录后修改密码。

 

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

查看数据库当前字符集参数设置SELECT * FROM v$nls_parameters;或select * from nls_database_parameters
客户端 NLS_LANG 的设置方法 Windows:
# 常用中文字符集set NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
# 常用unicode字符集set NLS_LANG=american_america.AL32UTF8
可以通过修改注册表键值永久设置HKEY_LOCAL_MACHINE/SOFTWARE/ORACLE/HOMExx/NLS_LANG

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

以一个表为基准更新另一个表:

UPDATE nadkey1
   SET nadkey = (SELECT nadkey2.nkn
                   FROM nadkey2
                  WHERE nadkey1.nadkey = nadkey2.nk0 and rownum=1)
 WHERE EXISTS (SELECT nkn
                 FROM nadkey2
                WHERE nadkey1.nadkey = nadkey2.nk0);


select name,sequence#,first_change#,next_change# from v$archived_log

select checkpoint_change# from v$database;

select checkpoint_change# from v$datafile;

select checkpoint_change# from v$datafile_header;

select group#,sequence#,first_change#,status from v$log;

insert into test values(dbms_flashback.get_system_change_number,'b')



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值