c f
三十四、sql编译执行顺序(假设kh_jbxx有N条记录,kh_dkhxx有n条记录) 1、不使用索引的全表扫描
例如:select * from kh_jbxx;
Oracle编译执行的时候采用如下步骤:
遍历全表的每一条记录,从表中读取出来,然后返回给客户端 时间复杂度:N
2、使用索引
例如:select * from kh_jbxx where khbh='0001'; //kh_jbxx.khbh是主键索引
oracle先去找kh_jbxx.khbh索引表,根据二分查找、哈希查找等查找方法找到khbh='0001'的索引值,然后根据索引值保存的khbh='0001'的记录的物理地址直接到kh_jbxx表中取出khbh='0001'对应的记录。
时间复杂度:log2N(根据具体的查找算法不同性能会有不同,但只要是唯一索引可以认为在瞬间就可以完成)
3、exists
例如:select * from kh_jbxx where exists(select 1 from kh_dkhxx where khbh=kh_jbxx.khbh);
//kh_dkhxx.khbh有索引
oracle遍历kh_jbxx的每一条记录,对于每一条记录再调用一个子查询过程:(根据传递过来的kh_jbxx.khbh查找kh_dkhxx中对应的记录,若有记录则返回相应的记录),若子查询返回的结果有记录,则主循环返回当条记录给客户端,然后继续下一条循环。 时间复杂度:N*log2n
4、无连接in
例如:select * from kh_jbxx where khbh in(select khbh from kh_dkhxx);
//客户基本信息表kh_jbxx记录数量远远大于大客户信息表kh_dkhxx,kh_jbxx.khbh和kh_dkhxx.khbh有索引
oracle循环遍历取出kh_dkhxx的记录放入内存临时表,然后循环遍历临时表的每条记录,对于每一条记录再调用一个子查询过程:(根据传递过来的kh_dkhxx.khbh查找kh_jbxx中对应的记录,若有记录则返回相应的记录),若子查询返回的结果有记录,则临时表的主循环返回当条记录给客户端,然后继续下一条循环。 时间复杂度:n*log2N
5、有连接in
例如:select * from kh_jbxx where khbh in(select khbh from kh_dkhxx where ydlb=kh_jbxx.ydlb);//kh_dkhxx.ydlb有索引
oracle循环遍历kh_jbxx的每一条记录,对于每一条记录再调用一个子查询过程:(根据传递过来的kh_jbxx.ydlb查找kh_dkhxx中对应的记录,若有记录则返回相应的记录),循环子查询返回的所有记录判断与主循环当前记录的客户遍号是否相同,若有相同的客户遍号则主循环返回当条记录给客户端,然后继续下一条循环。 时间复杂度:N*n/(ydlb的数量) 三十五、说明:
SQL格式简单,但是使用却可以灵活多样,子语句可以含有子语句,只有多用才能学好、用活。利用SQL可以实现任何查询或统计。
特别说明:在pb中执行一条delete或者insert或者update之后,必须后面有commit work或者rollback work;否则会将数据库中相应数据行锁住,直到断开连接时自动提交,当退出程序时才会断开连接。
21
常用命令、技巧、书写格式
一、启动数据库(开机时系统自动启动) 用 oracle7登录 $svrmgrl
svrmgrl>connect internal svrmgrl>startup
.......//看到oracle使用内存情况,与机器总内存比较,增加oracle使用内存数 svrmgrl>shutdown 所有会话断开后关闭 svrmgrl>shutdown immediate svrmgrl>shutdown abort 强行关闭 svrmgrl>exit $exit
二、initorac.ora(或 intiWG73.ora) logbuffer要大一点,
日志文件一定要比logbuffer大
logbuffer必须是dbblobsize整数倍。 Redobuffer增加就是logbuffer影响。 三、数据导出
(使用7.3倒入倒出数据是,服务器必须运行过catexp73.sql) exp help=y得到帮助 exp parfile=ydxt.exp 其中:ydxt.exp:
userid=system/manager@ydxt grants=y full=y
file=c:\\database\\ydxt200108170926.dmp log=c:\\database\\ydxt200108170926.log 或者
userid=system/manager@ydxt grants=y indexs=y
file=c:\\database\\ydxt200108170926.dmp log=c:\\database\\ydxt200108170926.log owner=(cur,cur2) rows=y
tables=(table1,table2) 四、数据导入
imp help=y得到帮助 imp parfile=ydxt.imp 其中:ydxt.imp:
userid=system/manager@ydxt grants=y full=y //采用system用户,可以自动创建表空间 file=c:\\database\\ydxt200108170926.dmp log=c:\\database\\ydxt200108170926.log
22
或者 根据用户
userid=system/manager@ydxt grants=y indexs=y
file=c:\\database\\ydxt200108170926.dmp log=c:\\database\\ydxt200108170926.log owner=(cur,cur2) 或者 导入几个表
userid=system/manager@ydxt grants=y indexs=y commit=y //导入100行自动提交 rows=y //导入数据,否则仅仅导入结构 ignore=y //忽略错误
file=c:\\database\\ydxt200108170926.dmp log=c:\\database\\ydxt200108170926.log fromuser=cur touser=cur1
tables=(table1,table2)
五、系统常用表
tab(tname,type) 当前用户所有表
all_tables(owner,table_name),所有用户所有表
sys.all_col_comments(table_name,owner,column_name)所有用户所有列 //修改同一个列的属性
删除一个用户所有表的方法:
select ‘drop table ‘ || tname || ‘;’ from tab; //drop table t1; //drop table t2;
将查询结果取出来再执行,就可以删除所有表
删除一个用户所有表的数据的方法(快速删除数据): select ‘truncate table ‘ || tname || ‘;’ from tab; //truncate table t1; //truncate table t2;
将查询结果取出来再执行,就可以删除所有表 把当前数据库中所有表的列gx去空格
select ‘update ‘ || table_name || ‘ set gx=ltrim(rtrim(gx));’ from sys.all_col_comments where column_name=’GX’;
把当前数据库中所有表的列gx=’套表’,改为1(字符串中单引号书写格式) select ‘update ‘ || table_name || ‘ set gx=’ ‘1’’ where gx =’’套表’’;’ from sys.all_col_comments where column_name=’GX’;
特别注意:oracle 不能用双引号“代替两个单引号‘,在oracle 中它代表转义字符,类似于c语言的/,如果需要引号,要写单引号‘,不能用双引号代替。 六、获取汉字拼音码 pb的函数
function getpy(string ) string //getpy(‘山东大学123’)=’sddx123’
23
oracle数据库函数
function getpy(string ) string //getpy(‘山东大学123’)=’sddx123’ 七、Sql语句启发方法
给所有需要处理的表造一系列例子数据(指需要相关的列,特别是条件列)写在纸上,例子数据尽可能代表一种类型,也就是例子数据要有代表性,如果同一个表相互关联,直接写成两个表这样就不会混淆。有了例子数据在写条件的时候就不会忘记相关限制,如果是update,可以通过箭头将子句的数据连接到主表要替换的数据上面,这样可以帮助你启发思路。
Person1
child_no child_name father_no father_name child_sex 1 张三 3 王五 f 2 李四 3 王五 m 3 王五 无父亲 m 4 姚六 3 王五 m 5 赵七 无父亲 f Person2
child_no child_name father_no father_name child_sex 1 张三 3 王五 f 2 李四 3 王五 m 3 王五 无父亲 m 4 姚六 3 王五 m 5 赵七 无父亲 f Update person t1
Set fathername=(select childname from person t2 where t1.father_no =t2.childno) Where exists(select 1 from person t2 where t1.fatherno=t2.childno)
八、Sql书写格式:
Select v1,v2,v3,v4,v5,v6,v7列数量不要超过7个 (select mc from t3 where ……),子句单列一行 V8, v9,v10,v11,v12,v13,v14 每行列数相等,左对齐 From T1,T2, 除非非常简单语句,否则单列一行
Where t1=t2 And t5=454-232 And exists( select ‘’ From Where ) And khbh in (select khbh
From Where ) 注意缩进以及对齐
24
ORACLE数据库SQL语言常用函数
一、伪列:
伪列不是表的真实列,但是你可以象使用真实列一样使用伪列,常用伪列:ROWID行的绝对物理编号,每一行是唯一的。ROWNUM序号,返回查询结果的每行序号。系统时间sysdate,返回系统当前时间。
例如:SELECT ROWID,ROWNUM,SNO,SNAME,sysdate FROM STUDENT; 二、伪表dual:
伪表不是真实表,但是你可以象使用真实表一样使用它,它仅有一行数据。
例如:select sysdate from dual; SELECT 123+10 FROM DUAL; (SELECT SYSDATE; 在SYBASE数据库是正确的!) 三、运算符:
算术计算:+、-、*、/。字符串相连 ||,not、and、 or。 四、日期运算:
SYSDATE + 1/24/60/60,就是当前时间加1秒。
日期运算:SYSDATE + 1,就是当前时间加1天; 五、数值函数:
绝对值ABS(n)、求余数MOD(m,n)、幂函数POWER(M,N)、四舍五入ROUND(N,[M])、截断函数TRUNC(N,[M])。
例如:SELECT COURSE,ABS(50 - COURSE) FROM SC; SELECT MOD(COURSE,10) FROM SC,
SELECT ROUND(COURSE,2) FROM SC; COURSE=13.345, ROUND(COURSE,2)=13.35 SELECT TRUNC(COURSE,2) FROM SC; COURSE=13.345, TRUNC(COURSE,2)=13.34 六、字符串查找函数:instr
Instr(‘1234567890’,’56’) 返回5 Instr(‘1234567890’,’a’) 返回0
七、字符函数:
ASCII转化为字符CHR(N)、字符串求小写LOWER(CHAR)、删除左边空格LTRIM(CHAR[,字符])、删除右边空格RTRIM(CHAR[,字符])、求子串SUBSTR(STRING,M,[N])、字符串求大写UPPER(CHAR)。
例如:CHR(48)=’0’
LOWER(‘Ab’)=’ab’ TRIM(‘ 123 ’)=’123’ LTRIM(‘ 123’)=’123’ RTRIM(‘1232III’,’I’)=’1232’ SUBSTR(‘123456’,4,2)=’45’ SUBSTR(‘123456’,2)=’23456’ UPPER(‘Ab’)=’AB’
例:去掉一个字符串的所有空格
Update student
Set sname=(substring(sname,instr(sname, ’ ’)-1))|| trim(substring(sname,instr(sname, ’ ’)+1)) Where instr(sname, ’ ’)>0;
八、日期函数:
日期增加月份ADD_MONTHS(DATE,N)、求日期当月最后一天LAST_DAY(DATE)、两个日期相差月份MONTH_BETWEEN(DATE1,DATE2)、日期四舍五入ROUND(DATE, [FMT])、日期截断TRUNC(DATE,[FMT])、返回系统时间SYSDATE()。
例如:ADD_MONTHS(2001-01-01,1)=2001-02-01
25