oracle 学习笔记
2013-09-12 13:13
281 查看
一:oracle语法(20130906)
1.语法: 语法NULLIF ( expression1, expression2)
语法NULLIF ( expression1 , expression2 ) 参数expression1,expression2 如果两个表达式不相等,NULLIF 返回第一个 expression1 的值。 如果两个表达式相等,NULLIF 返回空值NULL。 例: SELECT NULLIF('222','222') FROM DUAL; -- return SELECT NULLIF('222','') FROM DUAL; -- return |
NVL2(表达式,不为空设值,为空设值) |
2.操作实例 表A记录如下: aID aNum 1 a20050111 2 a20050112 3 a20050113 4 a20050114 5 a20050115 表B记录如下: bID bName 1 2006032401 2 2006032402 3 2006032403 4 2006032404 8 2006032408 实验如下: 1.left join sql语句如下: select * from A left join B on A.aID = B.bID 结果如下: aID aNum bID bName 1 a20050111 1 2006032401 2 a20050112 2 2006032402 3 a20050113 3 2006032403 4 a20050114 4 2006032404 5 a20050115 NULL NULL (所影响的行数为 5 行) 结果说明: left join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left join是以左表为准的. 换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID = B.bID). B表记录不足的地方均为NULL. 2.right join sql语句如下: select * from A right join B on A.aID = B.bID 结果如下: aID aNum bID bName 1 a20050111 1 2006032401 2 a20050112 2 2006032402 3 a20050113 3 2006032403 4 a20050114 4 2006032404 NULL NULL 8 2006032408 (所影响的行数为 5 行) 结果说明: 仔细观察一下,就会发现,和left join的结果刚好相反,这次是以右表(B)为基础的,A表不足的地方用NULL填充. 3.inner join sql语句如下: select * from A innerjoin B on A.aID = B.bID 结果如下: aID aNum bID bName 1 a20050111 1 2006032401 2 a20050112 2 2006032402 3 a20050113 3 2006032403 4 a20050114 4 2006032404 结果说明: 很明显,这里只显示出了 A.aID = B.bID的记录.这说明inner join并不以谁为基础,它只显示符合条件的记录. 还有就是inner join 可以结合where语句来使用 如: select * from A innerjoin B on A.aID = B.bID where b.bname='2006032401' 这样的话 就只会放回一条数据了 |
有两张表,分别为A、B,求得一个字段的值先在表A中寻找,如果A表中存在数据,则输出A表的值;如果A表中不存在,则在B表中寻找,若B表中有相应记录,则输出B表的值;如果B表中也不存在,则输出"no records”字符串。 with sql1 as (select to_char(a) s_name from test_tempa), sql2 as (select to_char(b) s_name from test_tempb where not exists (select s_name from sql1 where rownum=1)) select * from sql1 union all -- union含有distinct的功能 select * from sql2 union all -- UNION ALL只是简单的将两个结果合并后就返回 select 'no records' from dual where not exists (select s_name from sql1 where rownum=1) and not exists (select s_name from sql2 where rownum=1); WITH Clause方法的优点 : 增加了SQL的易读性,如果构造了多个子查询,结构会更清晰; 更重要的是:“一次分析,多次使用”,这也是为什么会提供性能的地方,达到了“少读”的目标。 |
连续求和分析函数。 |
二:oracle 创建临时表(20130909)
1. Oracle 中创建临时表语句create global temporary table TMP_TKZC_RETURN_APPRAISE_DAY ( CALC_PHASE VARCHAR2(50), BEG_DATE CHAR(10), END_DATE CHAR(10) ) on commit delete rows; -- 定义了建立事务级临时表的方法. --ON COMMIT DELETE ROWS 说明临时表是事务指定,每次提交后ORACLE将截断表(删除全部行) --ON COMMIT PRESERVE ROWS 说明临时表是会话指定,当中断会话时ORACLE将截断表。 详细介绍: Oracle临时表分为 会话级临时表 和 事务级临时表。 会话级临时表是指临时表中的数据只在会话生命周期之中存在,当用户退出会话结束的时候,Oracle自动清除临时表中数据。 事务级临时表是指临时表中的数据只在事务生命周期中存在。当一个事务结束(commit or rollback),Oracle自动清除临时表中数据。 临时表中的数据只对当前Session有效,每个Session都有自己的临时数据,并且不能访问其它Session的临时表中的数据。因此,临时表不需要DML锁。 |
pl/sql中的case语句 select (case when DUMMY='X' then 0 else 1 end) as flag from dual; case的第1种用法: case col when 'a' then 1 when 'b' then 2 else 0 end 这种用法跟decode一样没什么区别 case的第2种用法: case when score <60 then 'd' when score >=60 and score <70 then 'c' when score >=70 and score <80 then 'b' else 'a' end |
a) PROCEDURERAISE_APPLICATION_ERROR( error_number_in IN NUMBER, error_msg_in IN VARCHAR2);
RAISE_APPLICATION_ERROR(-20000, P_PIPE_NAME || ' 管道名称已经存在'); RAISE_APPLICATION_ERROR 是将应用程序专有的错误从服务器端转达到客户端应用程序(其他机器上的SQLPLUS或者其他前台开发语言). error_number_in 之容许从 -20000 到 -20999 之间,这样就不会与 ORACLE 的任何错误代码发生冲突。error_msg_in 的长度不能超过 2k,否则截取 2k。 DECLARE v_empno employees.employee_id%TYPE :=&empno; no_result EXCEPTION; --1、定义 BEGIN UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno; IF SQL%NOTFOUND THEN raise_application_error (-20000, ""NEW_EMP::hiredate cannot be in the future""); --3、抛出自定义异常 END IF; EXCEPTION when dup_val_on_index then raise_application_error (-20001, ""NEW_EMP::employee called ""||p_name||"" already exists"", true); --3、包装Oracle异常 WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||""---""||SQLERRM); END; |
DECLARE v_empno employees.employee_id%TYPE :=&empno; no_result EXCEPTION; --1、定义 BEGIN UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno; IF SQL%NOTFOUND THEN RAISE no_result; --2、抛出 END IF; EXCEPTION WHEN no_result THEN --3、处理惩罚 DBMS_OUTPUT.PUT_LINE(""你的数据更新语句失败了!""); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(SQLCODE||""---""||SQLERRM); END; |
-- SQL%ROWCOUNT CREATE OR REPLACE PROCEDURE test AS BEGIN update MY_TIME_TEST1 set discript = '6' where discript = '1' ; If sql%rowcount>1 then --上面update影响行数>1就插入到my_time_test1 insert into MY_TIME_TEST1 values(sysdate,'7'); end if; END; -- SQL%BULK_ROWCOUNT DECLARE TYPE deptno_table_type IS TABLE OF number(2); v_deptno_table deptno_table_type:=deptno_table_type(10,20,30); BEGIN FORALL i IN 1.. v_deptno_table.COUNT UPDATE emp2 SET sal=sal*0.5 WHERE deptno=v_deptno_table(i); dbms_output.put_line('DEPARTMENT_10:'||SQL%BULK_ROWCOUNT(1)||' rows'); dbms_output.put_line('DEPARTMENT_10:'||SQL%BULK_ROWCOUNT(1)||' rows'); dbms_output.put_line('DEPARTMENT_20:'||SQL%BULK_ROWCOUNT(2)||' rows'); dbms_output.put_line('DEPARTMENT_30:'||SQL%BULK_ROWCOUNT(3)||' rows'); END; / 参考:http://blog.csdn.net/inyutal/article/details/5819161 |
对于内部异常来说,SQLCODE会返回Oracle错误编号。SQLCODE 返回的总是一个负数,除非发生的Oracle错误是没有找到数据,这时返回的是+100。 SQLERRM会返回对应的错误消息。消息是以Oracle错误编号开头的。 如果我们没有使用编译指令EXCEPTION_INIT把异常与编号关联,SQLCODE和SQLERRM就会分别返回+1和消息"User-Defined Exception"。 Oracle错误消息最大长度是512个字符,其中包括错误编号、嵌套消息和具体表和字段的名称。 如果没有异常抛出,SQLCODE返回0,SQLERRM 返回消息"ORA-0000: normal, successful completion"。 我们可以把错误编号传递给SQLERRM,让它返回对应的错误消息。但是,一定要保证我们传递给SQLERRM的错误编号是负数。 |
通过bulk collect减少loop处理的开销 采用bulk collect可以将查询结果一次性地加载到collections中。 而不是通过cursor一条一条地处理。 可以在select into,fetch into,returning into语句使用bulk collect。 注意在使用bulk collect时,所有的into变量都必须是collections. 举几个简单的例子: --在select into语句中使用bulk collect DECLARE TYPE SalList IS TABLE OF emp.sal%TYPE; sals SalList; BEGIN -- Limit the number of rows to 100. SELECT sal BULK COLLECT INTO sals FROM emp WHERE ROWNUM <= 100; -- Retrieve 10% (approximately) of the rows in the table. SELECT sal BULK COLLECT INTO sals FROM emp SAMPLE 10; END; / --在fetch into中使用bulk collect DECLARE TYPE DeptRecTab IS TABLE OF dept%ROWTYPE; dept_recs DeptRecTab; CURSOR c1 IS SELECT deptno, dname, loc FROM dept WHERE deptno > 10; BEGIN OPEN c1; FETCH c1 BULK COLLECT INTO dept_recs; END; / --在returning into中使用bulk collect CREATE TABLE emp2 AS SELECT * FROM employees; DECLARE TYPE NumList IS TABLE OF employees.employee_id%TYPE; enums NumList; TYPE NameList IS TABLE OF employees.last_name%TYPE; names NameList; BEGIN DELETE FROM emp2 WHERE department_id = 30 RETURNING employee_id, last_name BULK COLLECT INTO enums, names; dbms_output.put_line('Deleted ' || SQL%ROWCOUNT || ' rows:'); FOR i IN enums.FIRST .. enums.LAST LOOP dbms_output.put_line('Employee #' || enums(i) || ': ' || names(i)); END LOOP; END; / DROP TABLE emp2; RETURNING into语句 DELETE操作:RETURNING返回的是DELETE之前的结果; INSERT操作:RETURNING返回的是INSERT之后的结果; UPDATE操作:的RETURNING语句是返回UPDATE操作之后的结果。 www.2cto.com INSERT INTO SELECT语句不支持。 MERGE语句不支持RETURNING语句。 |
三:UNION 、UNION ALL(20130910)
1、UNION 、UNION ALLUNION 操作符用于合并两个或多个 SELECT 语句的结果集。 请注意,UNION 内部的 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条 SELECT 语句中的列的顺序必须相同。 UNION ALL 命令和 UNION 命令几乎是等效的,不过 UNION ALL 命令会列出所有的值。 |
总和:∑,连乘:∏,从n个元素中取出r个元素所有不同的组合数:C(n,r) ,幂(A,Ac,Aq,x^n)等。 |
扩展已知的数组空间,例: DECLARE TYPE CourseList IS TABLE OF VARCHAR2(10); courses CourseList; BEGIN -- 初始化数组元素,大小为3 courses := CourseList( 'Biol 4412 ', 'Psyc 3112 ', 'Anth 3001 '); -- 为数组增加一个元素,数组大小为4,末尾的元素为NULL courses.EXTEND; -- append one null element -- 为增加的元素赋值,如果没用EXTEND,这里会出错 courses(4) := 'Engl 2005 '; end Oracle 在逻辑上是由各个表空间(tablespace)构成的, tablespace由segments(段)构成 段是由extends构成 中文叫作区 或者数据区 区是由一个一个的数据块构成 数据块的大小由操作系统决定。 |
动态SQl中用using传递参数 下边这种写法对吗? execute immediate 'select * from 表 where 字段1 = :1 and 字段2 = :1' using '1'; -- 如果前面已经定义了变量则可以这样使用 还是说 必须写成: execute immediate 'select * from 表 where 字段1 = :1 and 字段2 = :2' using '1','1'-- 如果前面已经定义了变量则可以这样使用 我的动态SQL里边 很多地方都用到了同一个参数,用一次 就得在using后边加一个吗? 动态SQL语句中的占位符与USING子句中的绑定参数是位置关联的,而不是名称关联。所以,如果在SQL语句中同样的占位符出现两次或多次,那么,它的每次出现都必须与一个USING子句中的绑定参数相关联。 http://bbs.csdn.net/topics/390439524?page=1 |
SYS_GUID (),是Oracle 8i 后提供的函数。SYS_GUID产生并返回一个全球唯一的标识符(原始值)由16个字节组成。在大多数平台,生成的标识符由主机标符,执行函数的进程或者线程标识符,和进程或线程的一个非重复的值(字节序列)组成。 |
SELECT SYSTIMESTAMP , Sysdate FROM dual ; Systimestamp 函数返回本机数据库上当前系统日期和时间(包括微秒和时区)。 Systimestamp : 10-9月 -13 02.49.23.281000 下午 +08:00 , sysdate: 2013-9-10 14:49:23 |
CREATE OR REPLACE TYPE "VAR_LIST" -- 自己定义变量 V_TABLE VAR_LIST := VAR_LIST(); -- 给此变量开辟空间 V_TABLE.EXTEND; -- 像一个数组,扩展下空间 V_TABLE(V_TABLE.LAST) := V_VALUE; |
四: lag 函数(20130911)
1.lag()函数lag(要显示的前一行字段,从第几行开始,给此字段的默认值) 。 LAG()和LEAD()统计函数可以在一次查询中取出同一字段的前N行的数据和后N行的值。这种操作可以使用对相同表的表连接来实现,不过使用LAG和 LEAD有更高的效率。 |
相关文章推荐
- Oracle PLSQL 学习笔记三
- java 从零开始,学习笔记之基础入门<Oracle_基础>(三十三)
- ORACLE PL/SQL 集合学习笔记(一)
- oracle 学习笔记四
- Oracle 11g学习笔记(10)
- Oracle 10g数据库学习笔记
- Oracle学习笔记[5] - win2000/xp/2003下完全卸载ORACLE
- Oracle 学习笔记(12)
- ORACLE MODEL子句学习笔记
- oracle 11g 学习笔记 10_31_管理表空间和数据文件
- 23.Oracle深度学习笔记——内存架构之SGA Buffer Cache
- Oracle 备份与恢复学习笔记(4)
- oracle 11g 学习笔记 10_31(2)_维护数据的完整性
- Oracle 备份与恢复学习笔记(9_2)
- Oracle 学习笔记 11 -- 视图 (VIEW)
- 2018年作为一个新手的Oracle(DBA)学习笔记
- Oracle 学习笔记 12 -- 序列、索引、同义词
- JDBC学习笔记,以oracle 9i为例。
- Oracle数据库技术实用详解学习笔记:在RedHat AS 4中安装oracle 10gr2
- Oracle 学习笔记1