Oracle数据库中大小写敏感
要求找出含有%的记录
这需要使用ESCAPE标识转义字符
select * from t_charwhere a like ‘%\%%' escape '\';
select * fromt_char where a like ‘%K%%' escape ‘K';
PLSQL中日期比较
1.格式需要一致,可以通过字符串比较。
2.TO_CHAR(CREATE_DATE,'yyyy-mm-dd')>=NVL(P_CREATE_FROMDATE,TO_CHAR(CREATE_DATE,'yyyy-mm-dd'))
2. START_DATE <= TO_date(p_trans_date,'YYYY-MM-DD')
--不易发现的错误
select * from test1where column1 ='1234';--将所有行转换为字符串
select * from test1where column1 =1234;--将所有行转换为数字,包含字符的行出错
--连接
-oracle全外外连接
select e.last_name,e.department_id,d.department_namefrom employees e,departments dwhere e.department_id=d.department_id(+)union
select e.last_name,e.department_id,d.department_namefrom employees e,departments dwhere e.department_id(+)=d.department_id;
--sql1999标准
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
FULLOUTERJOIN departments d
ON (e.department_id =d.department_id) ;
分组计算函数和group by子句
备注:MIN, MAX 可用于任何数据类型,但AVG, SUM,STDDEV,VARIANCE仅适用于数值型字段。
使用GROUP BY 子句进行分组:
l 可以按照某一个字段分组,也可以按照多个字段的组合进行分组
l SELECT查询语句中同时选择分组计算函数表达式和其他独立字段时,其他字段必须出现在Group By子句中,否则不合法。
l 不能在Where条件中使用分组计算函数表达式,当出现这样的需求的时候,使用Having 子句。
l 分组计算函数也可嵌套使用。
事务控制
隐式的事务提交或回滚动作:
Commit,rollback 是显式的提交和回滚语句,还有一些隐式的提交和回滚是大家需要知道并引起注意的:
当如下事件发生是,会隐式的执行Commit动作:
1、数据定义语句被执行的时候,比如新建一张表:Create Table …
2、数据控制语句被执行的时候,比如赋权GRANT …( 或者DENY)
3、正常退出iSQL*Plus 或者PLSQLDEVELOPER, 而没有显式的执行COMMIT 或者ROLLBACK 语句。
当如下事件发生时,会隐式执行Rollback 动作:
1、非正常退出iSQL*Plus, PLSQL DEVELOPER, 或者发生系统错误。
在Commit 或者Rollback前后数据的状态:
1、在数据已经被更改,但没有Commit前,被更改记录处于被锁定状态,其他用户无法进行更改;
2、在数据已经被更改,但没有Commit前,只有当前Session的用户可以看到这种变更,其他Session的用户
看不到数据的变化。
3、在数据已经被更改,并且被Commit后,被更改记录自动解锁,其他用户可以进行更改;
4、在数据已经被更改,并且被Commit后,其他Session的用户再次访问这些数据时,看到的是变化后的数据。
那么同理可知Rollback前后数据的状态及锁的变化。
锁
表的命名要求和表中列的命名要求:
1、必须以字母开头
2、长度不能超过30个字符
3、只能包含A–Z,a–z, 0–9,_, $, and #
4、不能与数据库中的已有对象重名
5、不能使用Oracle 数据库的保留字
注意TRUNCATE 与DELETE FROM table 的区别: 1)没有Rollback机会2)HWM标记复位(HWM高水位线)都不会删除表结构
约束
更改表的语法:
添加列:
ALTERTABLE table
ADD(column datatype [DEFAULT expr]
[, columndatatype]...);
更改列:
ALTERTABLE table
MODIFY(column datatype [DEFAULT expr]
[, columndatatype]...);
删除列:
ALTERTABLE table
DROP(column);
ALTER TABLE tablenameADD CONSTRAINT constraintname
constrainttype(column1,…);
CONSTRAINT emp_email_ukUNIQUE(email))
CONSTRAINT dept_id_pk PRIMARYKEY(department_id))
CONSTRAINT emp_dept_fk FOREIGN KEY (department_id)
REFERENCESdepartments(department_id)
CONSTRAINT emp_salary_min CHECK (salary > 0)
索引、序列、同义词
函数索引
CREATE INDEX upper_dept_name_idx
ON departments(UPPER(department_name));
控制用户权限
GRANT object_priv [(columns)]
ON object
TO {user|role|PUBLIC}
[WITHGRANT OPTION];
如果你想让其他用户也有权把你赋给他的权限进一步赋予给别人,那么需要带WITH GRANT OPTION;
GRANT select, insert
ON departments
TO scott
WITH GRANT OPTION;
撤销权限
REVOKE {privilege [, privilege...]|ALL}
ON object
FROM{user[, user...]|role|PUBLIC}
创建DB-LINK,通过DB-LINK访问另一数据库中的表
CREATE PUBLIC DATABASE LINK hq.acme.com
USING'sales';
SELECT*
递归查询
SELECTlast_name||' reports to '||
PRIORlast_name "Walk Top Down"
FROMemployees
STARTWITH last_name = 'King'
CONNECTBY PRIOR employee_id = manager_id ;
使用LEVEL关键字和LPAD函数,在OUTPUT中显示树形层次。
SELECT LPAD(last_name,LENGTH(last_name)+(LEVEL*2)-2,'_')
AS org_chart
FROM employees
START WITH last_name='King'
CONNECT BYPRIOR employee_id=manager_id
Group By 子句的增强
在Group By 中使用Rollup 产生常规分组汇总行以及分组小计
在Group By 中使用Cube 产生Rollup结果集+ 多维度的交叉表数据源
GROUPING函数:Rollup 和Cube有点抽象,他分别相当于n+1 和2的n次方常规Group by 运
算;那么在Rollup 和Cube的结果集中如何很明确的看出哪些行是针对那些列或者列的组合进行
分组运算的结果的? 答案是可以使用Grouping 函数; 没有被Grouping到返回1,否则返回0
使用Grouping Set 来代替多次UNION
Exercise
--14. Showall employees who have managers with a salary higher than $15,000.
--Show the following data: employeename, manager name, manager salary, and salary grade of the manager.
createtable job_grades(grade_levelvarchar(20),lowest_salnumber,highest_salnumber);
insertinto job_gradesvalues('E',10000,1000000);
insertinto job_gradesvalues('E',9000,900000);
SELECT e.last_name, m.last_name manager,m.salary, j.grade_level
FROM employees e,employees m, job_grades j
WHERE e.manager_id = m.employee_id
AND m.salaryBETWEEN j.lowest_salAND j.highest_sal
AND m.salary >15000;
--15. Showthe department number, name, number of employees, and average salary of alldepartments,
--together with the names, salaries,and jobs of the employees working in each department.
SELECT d.department_id,
d.department_name,
count(e1.employee_id)employees,
NVL(TO_CHAR(AVG(e1.salary),'99999.99'),'No average') avg_sal,
e2.last_name,
e2.salary,
e2.job_id
FROM departments d,employees e1, employees e2
WHERE d.department_id = e1.department_id(+)
AND d.department_id =e2.department_id(+)
GROUPBY d.department_id,
d.department_name,
e2.last_name,
e2.salary,
e2.job_id
ORDERBY d.department_id, employees;
--19. Showthe employee number, last name, salary, department number, and the averagesalary in their department for all employees.
select e.employee_id, e.last_name,e.department_id,avg(d.salary)
from employees d,employees e
where d.department_id = e.department_id
groupby e.employee_id, e.last_name, e.department_id;
--31. Write a query to delete the oldestJOB_HISTORY row of an employee bylooking up the
--JOB_HISTORY table for theMIN(START_DATE) for the employee.
--Delete the records of only those employees who have changed at leasttwo jobs.
--If your query executes correctly, you will get the feedback:
DELETEFROM job_history JH
WHERE employee_id = (SELECT employee_id
FROM employees E
WHERE JH.employee_id = E.employee_id
AND START_DATE =
(SELECTMIN(start_date)
FROM job_history JH
WHERE JH.employee_id =E.employee_id)
AND3 > (SELECTCOUNT(*)
FROM job_history JH
WHERE JH.employee_id =E.employee_id
GROUPBY EMPLOYEE_ID
HAVINGCOUNT(*) >=2));
--41. Write a SQL script file to dropall objects (tables, views, indexes, sequences, synonyms, and so on) that youown.
SET HEADINGOFF ECHOOFF FEEDBACKOFF
SET PAGESIZE0
SELECT'DROP' || object_type ||' ' || object_name ||';'
FROM user_objects
ORDERBY object_type
SET HEADINGON ECHOON FEEDBACKON
SET PAGESIZE24
1. Oracle 同义词
相当于alias(别名),比如把user1.table1在user2中建一个同义词table1
create synonym table1 for user1.table1;
这样当你在user2中查select * from table1时就相当于查select * from user1.table1;
优点自己总结吧。
2. Oracle 受权 ORA-00990: 权限缺失或无效
创建一个用户:
create user xxx identified by yyy
当密码里面有特殊字符时 windows平台下面应该用 "yyy" 其它平台未测试
刚创建好的用户是没有任何权限的 连登录数据库的权限都没有
这时,就要给用户授予权限:
ORACLE里面的权限有系统权限和对象权限两种
可以通过
select distinct p.privilege
from user_sys_privs p
order by p.privilege asc;
来查询ORACLE里面的所有系统权限;
常用的系统权限有 :
CREATE SESSION 创建会话 登录数据库
CREATE SEQUENCE 创建序列
CREATE SYNONYM 创建同名对象
CREATE TABLE 在用户模式中创建表
CREATE ANY TABLE 在任何模式中创建表
DROP ANY TABLE 在任何模式中删除表
CREATE PROCEDURE 创建存储过程
EXECUTE ANY PROCEDURE 执行任何模式的存储过程
CREATE USER 创建用户
DROP USER 删除用户
CREATE VIEW 创建视图
通过下面的SQL可以查询所有的对象权限:
select distinct t.privilege fromuser_tab_privs t;
结果如下:
FLASHBACK
EXECUTE
ONCOMMIT REFRESH
ALTER
DEQUEUE
UPDATE
DELETE
DEBUG
UNDER
QUERY REWRITE
SELECT
READ
INSERT
INDEX
WRITE
REFERENCES
MERGE VIEW
另外还有角色授权 可以通过下面的SQL来查询ORALCE里面内置有哪些角色:
select distinct r.granted_role role_name
from user_role_privs r
where r.default_role = 'YES'
order by role_name asc;
授权语句:grant 权限
系统授权直接写:grant 权限名称 to 用户名;
对象权限则要写成:grant 权限名称 on schema. 对象名 to 用户名
还要注意一点是:授予权的时候系统权限和对象权限不能同时写,也就是说不能写成下面这个样子:
GRANT CREATE TABLE, SELECT ON scott.testTO scott1
这样写会报 ORA-00990:权限缺失或无效
但是系统权限和角色是可以同时写在一起授予给某一个用户的
3. oracle之报错:ORA-00054: 资源正忙,要求指定NOWAIT
解决方案:
select session_id from v$locked_object; --首先得到被锁对象的session_id
SELECT sid, serial#, username, osuser FROM v$sessionwhere sid = session_id; --通过上面得到的session_id去取得v$session的sid和serial#,然后对该进程进行终止。
ALTER SYSTEM KILL SESSION 'sid,serial';
example:
ALTER SYSTEM KILL SESSION '13, 8';
--ora0054
--查找锁定的会话
select session_idfromv$locked_object;
SELECTsid, serial#,username, osuser
FROM v$session
wheresidin (4908,4913,4955);
--杀死会话
ALTERSYSTEMKILLSESSION'4908,2223';
ALTERSYSTEMKILLSESSION'4913,937';
ALTERSYSTEMKILLSESSION'4955,3079';
--查找锁
select *from v$lockwhereblock=1;
select *from v$locked_object;
--查看当前用户的一些权限
selectdistinct p.privilegefromuser_sys_privs p;
4. ORACLE-关于ORA-04021得解决办法(timeout occurred while waiting to lock object)
某个应用正在锁定该表或者包
表为
select b.SID,b.SERIAL#, c.SQL_TEXT
from v$locked_object a, v$session b,v$sqlarea c
where a.SESSION_ID = b.SID
and b.SQL_ADDRESS = c.ADDRESS
and c.sql_textlike'%table_name%'
包为
select B.SID,b.USERNAME, b.MACHINE, B.SERIAL#
FROM V$ACCESS A, V$SESSION B
WHERE A.SID = B.SID
and a.OBJECT ='%PACKAGE_name%'
and a.TYPE ='PACKAGE'
找出这个session
然后 kill
alter system kill session 'sid,serial#'
5. 层次查询实例也可以利用两个嵌套的游标实现
PLSQL\PACKAGE_GET_AUDIT_DESC.pck
selectdistinct x.form_kind, x.form_no, auditm
from (selectt.FORM_KIND,
t.FORM_NO,
substr(sys_connect_by_path(t.AUDITM,','),2) auditm,
level lv,
max(level)over(partitionbyt.FORM_KIND, t.FORM_NO) max_level
fromdw_tes_flow_audit_fs_v t
where1 =1
/*and t.FORM_KIND= 'SYS.FORM.009'
andt.FORM_NO = '277721'*/
andconnect_by_isleaf =1
connectbyprior t.FORM_KIND= t.FORM_KIND
andprior t.FORM_NO =t.FORM_NO
andprior t.AUDITM< t.AUDITM) x
where lv =max_level;
6. UNION和UNION ALL
Union,对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;
UnionAll,对两个结果集进行并集操作,包括重复行,不进行排序;
7. dbms_mview.refresh()函数
dbms_mview.refresh('表名', 'F') --快速刷新,也就是增量刷新
dbms_mview.refresh('表名', 'C') --完全刷新
详见http://www.linuxidc.com/Linux/2011-12/48463.htm
8. 动态游标运用
DECLARE
-- Localvariables here
a VARCHAR2(20);
l_cursor NUMBER;
l_state NUMBER;
l_sql VARCHAR2(2000);
l_name VARCHAR2(100);
BEGIN
-- Teststatements here
a := '''' ||'A' ||'''' ||',' ||'''' ||'B' ||'''';
dbms_output.put_line('a: ' || a);
l_sql := 'select namefrom cux_test t where t.name in (' || a ||')';
dbms_output.put_line('sql: ' || l_sql);
l_cursor :=dbms_sql.open_cursor;
dbms_sql.parse(l_cursor,l_sql, dbms_sql.native);
dbms_sql.define_column(l_cursor,1, l_name,100);
l_state :=dbms_sql.EXECUTE(l_cursor);
LOOP
EXITWHENdbms_sql.fetch_rows(l_cursor) <= 0;
dbms_sql.column_value(l_cursor,1, l_name);
dbms_output.put_line('result: ' || l_name);
ENDLOOP;
END;
9. 如果在本机可以正常使用,可是到局域网中的其他机器就出现“ORA-12170:TNS:连接超时
解决方法: 1.cmd-----ping ip地址查看网络问题,看能否ping通 2.cmd-----tnsping ip地址(或者是服务器的实例名SID)如果报“TNS-12535:操作超时”,可能是服务器端防火墙 没有关闭 3.cmd----netstat -na 查看1521端口是否关闭,如果关闭Windows XP中的防火墙设置中将1521端口设为例外 4.cmd----lsnrctl status lsnrctl是listener-control 监听器的缩写,查看监听的状态
10. 窗口切换诸多不便,上网搜了一下需要这么整:
tools -> window list(笔者注:变成打勾状态)
在tools->preferences->user interface->options 里面钩上 Autosavedesktop
不然每次重开pl/sql developer时都要调整位置
11. Plsql执行计划
Plsq F5键详见http://www.fengfly.com/plus/view-210418-1.html
http://alexgao.iteye.com/blog/1562962
12. SQL的内连接与外连接
http://blog.163.com/cs_mayong/blog/static/9581317120096595410120/
http://blog.csdn.net/yiluoak_47/article/details/7449590
1)左连接:Left Join或Left Outer Join
左连接的结果集包括LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(Null)。
2) 右连接:Right Join或Right Outer Join
右连接和左连接相反,它将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值(Null)。
3) 完整外部联接:Full Join或 Full Outer Join
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。
另一种方式"(+)"所在位置的另一侧为连接的方向
总之,
左连接显示左边全部的和右边与左边相同的
右连接显示右边全部的和左边与右边相同的
13. Oracle的方案(Schema)和用户(User)的区别
oracle中的schema就是指一个用户下所有对象的集合,schema本身不能理解成一个对象,oracle并没有提供创建schema的语法,schema也并不是在创建user时就创建,而是在该用户下创建第一个对象之后schema也随之产生,只要user下存在对象,schema就一定存在,user下如果不存在对象,schema也不存在;这一点类似于temp tablespace group,另外也可以通过oem来观察,如果创建一个新用户,该用户下如果没有对象则schema不存在,如果创建一个对象则和用户同名的schema也随之产生。
http://blog.csdn.net/kimsoft/article/details/4627520
http://blog.sina.com.cn/s/blog_6c845fae0100peof.html