Oracle supplies many PL/SQL packages with the Oracle server
to extend database functionality and provide PL/SQL access to SQL features.
You can use the supplied packages when creating your applications or for ideas in creating your own stored procedures.
This manual covers the packages provided with the Oracle database server.
Packages supplied with other products, such as Oracle Developer or the Oracle Application Server, are not covered.
Note that not every package or type described in this manual or elsewhere in the
Oracle Database Documentation Library is installed by default. In such cases, the
documentation states this and explains how to install the object. Run this query as a
suitably privileged user:
A packageis an encapsulated collection of related program objects stored together in
the database. Program objects are procedures, functions, variables, constants, cursors,
and exceptions.
http://www.itpub.net/thread-1830016-1-1.html dimensions这个模式对象类型
函数
dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。我们可以用它来做很多事情,
1、查看当前用户,可以在 SQL Plus中执行下面语句
select user from dual;
2、用来调用系统函数
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;--获得当前系统时间
select SYS_CONTEXT('USERENV','TERMINAL') from dual;--获得主机名
select SYS_CONTEXT('USERENV','language') from dual;--获得当前 locale
select dbms_random.random from dual;--获得一个随机数
3、得到序列的下一个值或当前值,用下面语句
select your_sequence.nextval from dual;--获得序列your_sequence的下一个值
select your_sequence.currval from dual;--获得序列your_sequence的当前值
4、可以用做计算器
select 7*9 from dual;
select sysdate from dual;
Oracle系统中dual表是一个“神秘”的表,网上有很多网友都对该表进行了测试,该表只有一行一列,其实该表和系统中的其他表一样,一样可以执行插入、更新、删除操作,还可以执行drop操作。但是不要去执行drop表的操作,否则会使系统不能用,数据库起不了,会报Database startup crashes with ORA-1092错误。此时也不要慌乱,可以通过执行以下步骤来进行恢复。
dual是一个什么对象呢?
SQL> select owner,object_name,object_type from dba_objects where object_name like '%DUAL%';
OWNER OBJECT_NAM OBJECT_TYPE
-------------------- ---------- -------------------
SYS DUAL TABLE
PUBLIC DUAL SYNONYM
原来DUAL是属于SYS schema的一个表,然后以PUBLIC SYNONYM的方式供其他数据库USER使用.
再看看它的结构:
desc dual
只有一个名字叫DUMMY的字符型COLUMN.
再查询一下表里的数据
SQL> select dummy from dual;
D
-
X
SQL> insert into dual values ( 'Y');
1 row created.
SQL> commit;
Commit complete.
SQL> select count(*) from dual;
COUNT(*)
----------
1
刚才插入的那条记录并没有显示出来 ! 明明DUAL表中有两条记录, 可就是只显示一条!
原来ORACLE对DUAL表的操作做了一些内部处理,尽量保证DUAL表中只返回一条记录
select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ') space from dual;
select chr(54740) zhao,chr(65) chr65 from dual;
一、字符函数
字符函数是oracle中最常用的函数,我们来看看有哪些字符函数:
lower(char):将字符串转化为小写的格式。
upper(char):将字符串转化为大写的格式。
length(char):返回字符串的长度。
substr(char, m, n):截取字符串的子串,n代表取n个字符的意思,不是代表取到第n个
replace(char1, search_string, replace_string)
instr(C1,C2,I,J) -->判断某字符或字符串是否存在,存在返回出现的位置的索引,否则返回小于1;在一个字符串中搜索指定的字符,返回发现指定的字符的位置;
C1 被搜索的字符串
C2 希望搜索的字符串
I 搜索的开始位置,默认为1
J 出现的位置,默认为1
问题:将所有员工的名字按小写的方式显示
SQL> select lower(ename) from emp;
问题:将所有员工的名字按大写的方式显示。
SQL> select upper(ename) from emp;
问题:显示正好为5个字符的员工的姓名。
SQL> select * from emp where length(ename)=5;
问题:显示所有员工姓名的前三个字符。
SQL> select substr(ename, 1, 3) from emp;
问题:以首字母大写,后面小写的方式显示所有员工的姓名。
SQL> select upper(substr(ename,1,1)) || lower(substr(ename,2,length(ename)-1)) from emp;
问题:以首字母小写,后面大写的方式显示所有员工的姓名。
SQL> select lower(substr(ename,1,1)) || upper(substr(ename,2,length(ename)-1)) from emp;
问题:显示所有员工的姓名,用“我是老虎”替换所有“A”
SQL> select replace(ename,'A', '我是老虎') from emp;
问题:instr(char1,char2,[,n[,m]])用法
SQL> select instr('azhangsanbcd', 'zhangsan') from dual; --返回2
SQL> select instr('oracle traning', 'ra', 1, 1) instring from dual; --返回2
SQL> select instr('oracle traning', 'ra', 1, 2) instring from dual; --返回9
SQL> select instr('oracle traning', 'ra', 1, 3) instring from dual; --返回0,根据条件,由于ra只出现二次,第四个参数3,就是说第3次出现ra的位置,显然第3次是没有再出现了,所以结果返回0。注意空格也算一个字符
SQL> select instr('abc','d') from dual; --返回0
二、数学函数
数学函数的输入参数和返回值的数据类型都是数字类型的。数学函数包括cos,cosh,exp,ln, log,sin,sinh,sqrt,tan,tanh,acos,asin,atan,round等
我们讲最常用的:
round(n,[m]) 该函数用于执行四舍五入,
如果省掉m,则四舍五入到整数。
如果m是正数,则四舍五入到小数点的m位后。
如果m是负数,则四舍五入到小数点的m位前。
eg、SELECT round(23.75123) FROM dual; --返回24
SELECT round(23.75123, -1) FROM dual; --返回20
SELECT round(27.75123, -1) FROM dual; --返回30
SELECT round(23.75123, -3) FROM dual; --返回0
SELECT round(23.75123, 1) FROM dual; --返回23.8
SELECT round(23.75123, 2) FROM dual; --返回23.75
SELECT round(23.75123, 3) FROM dual; --返回23.751
trunc(n,[m]) 该函数用于截取数字。
如果省掉m,就截去小数部分,
如果m是正数就截取到小数点的m位后,
如果m是负数,则截取到小数点的前m位。
eg、SELECT trunc(23.75123) FROM dual; --返回23
SELECT trunc(23.75123, -1) FROM dual; --返回20
SELECT trunc(27.75123, -1) FROM dual; --返回20
SELECT trunc(23.75123, -3) FROM dual; --返回0
SELECT trunc(23.75123, 1) FROM dual; --返回23.7
SELECT trunc(23.75123, 2) FROM dual; --返回23.75
SELECT trunc(23.75123, 3) FROM dual; --返回23.751
mod(m,n)取余函数
eg、select mod(10,2) from dual; --返回0
SELECT MOD(10,3) FROM dual; --返回1
floor(n) 返回小于或是等于n的最大整数
ceil(n) 返回大于或是等于n的最小整数
eg、SELECT ceil(24.56) from dual; --返回25
SELECT floor(24.56) from dual; --返回24
abs(n) 返回数字n的绝对值
对数字的处理,在财务系统或银行系统中用的最多,不同的处理方法,对财务报表有不同的结果
三、日期函数
日期函数用于处理date类型的数据。默认情况下日期格式是dd-mon-yy 即“12-7 月-12”
(1)sysdate 返回系统时间
eg、SQL> select sysdate from dual;
(2)oracle add_months函数
oracle add_months(time,months)函数可以得到某一时间之前或之后n个月的时间
eg、select add_months(sysdate,-6) from dual; --该查询的结果是当前时间半年前的时间
select add_months(sysdate,6) from dual; --该查询的结果是当前时间半年后的时间
(3)last_day(d):返回指定日期所在月份的最后一天
问题:查找已经入职8个月多的员工
SQL> select * from emp where sysdate>=add_months(hiredate,8);
问题:显示满10年服务年限的员工的姓名和受雇日期。
SQL> select ename, hiredate from emp where sysdate>=add_months(hiredate,12*10);
问题:对于每个员工,显示其加入公司的天数。
SQL> select floor(sysdate-hiredate) "入职天数",ename from emp;
或者
SQL> select trunc(sysdate-hiredate) "入职天数",ename from emp;
问题:找出各月倒数第3天受雇的所有员工。
SQL> select hiredate,ename from emp where last_day(hiredate)-2=hiredate;
四、转换函数
转换函数用于将数据类型从一种转为另外一种。在某些情况下,oracle server允许值的数据类型和实际的不一样,这时oracle server会隐含的转化数据类型
比如:
create table t1(id int);
insert into t1 values('10');--这样oracle会自动的将'10' -->10
create table t2 (id varchar2(10));
insert into t2 values(1); --这样oracle就会自动的将1 -->'1';
我们要说的是尽管oracle可以进行隐含的数据类型的转换,但是它并不适应所有的情况,为了提高程序的可靠性,我们应该使用转换函数进行转换。
to_char()函数
你可以使用select ename, hiredate, sal from emp where deptno = 10;显示信息,可是,在某些情况下,这个并不能满足你的需求。
问题:日期是否可以显示 时/分/秒
SQL> select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss') from emp;
问题:薪水是否可以显示指定的货币符号
SQL>
yy:两位数字的年份 2004-->04
yyyy:四位数字的年份 2004年
mm:两位数字的月份 8 月-->08
dd:两位数字的天 30 号-->30
hh24: 8点-->20
hh12:8点-->08
mi、ss-->显示分钟\秒
9:显示数字,并忽略前面0
0:显示数字,如位数不足,则用0补齐
.:在指定位置显示小数点
,:在指定位置显示逗号
$:在数字前加美元
L:在数字前面加本地货币符号
C:在数字前面加国际货币符号
G:在指定位置显示组分隔符、
D:在指定位置显示小数点符号(.)
问题:显示薪水的时候,把本地货币单位加在前面
SQL> select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss'), to_char(sal,'L99999.99') from emp;
问题:显示1980年入职的所有员工
SQL> select * from emp where to_char(hiredate, 'yyyy')=1980;
问题:显示所有12月份入职的员工
SQL> select * from emp where to_char(hiredate, 'mm')=12;
to_date()函数
函数to_date用于将字符串转换成date类型的数据。
问题:能否按照中国人习惯的方式年—月—日添加日期。
eg、SELECT to_date('2012-02-18 09:25:30','yyyy-mm-dd hh24:mi:ss') FROM dual;
五、sys_context()系统函数
1)terminal:当前会话客户所对应的终端的标示符,如计算机名
2)language: 语言
3)db_name: 当前数据库名称
4)nls_date_format: 当前会话客户所对应的日期格式
5)session_user: 当前会话客户所对应的数据库用户名
6)current_schema: 当前会话客户所对应的默认方案名
7)host: 返回数据库所在主机的名称
通过该函数,可以查询一些重要信息,比如你正在使用哪个数据库?
select sys_context('USERENV','db_name') from dual;
注意:USERENV是固定的,不能改的,db_name可以换成其它,
例如:
select sys_context('USERENV','language') from dual;
select sys_context('USERENV','current_schema') from dual;
SQL> select sysdate from dual; SYSDATE --------- 09-JUL-15 SQL> select add_months(sysdate,-4) from dual; ADD_MONTH --------- 09-MAR-15 SQL> select add_months(sysdate,+4) from dual; ADD_MONTH --------- 09-NOV-15 SQL> select last_day(sysdate) from dual; LAST_DAY( --------- 31-JUL-15
存储过程
http://www.cnblogs.com/chinafine/articles/1776085.html
1。预编译,已优化,效率较高。避免了SQL语句在网络中传输然后再解释的低效率。
2。如果公司有专门的DBA,写存储过程可以他来做,程序员只要按他提供的接口调用就好了。这样分开来做,比较清楚。
3。修改方便。嵌入在程序中的SQL语句修改比较麻烦,而且经常不能肯定该改的是不是都改了。SQLSERVER上的存储过程修改就比较方便,直接改掉该存储过程,调用它的程序基本不用动,除非改动比较大(如改了传入的参数,返回的数据等)。
4。会安全一点。不会有SQL语句注入问题。
当然,也有缺点。特别是业务逻辑比较复杂时,全用存储过程来写,估计也累的够呛。
1。SQL存储过程执行起来比SQL命令文本快得多。当一个SQL语句包含在存储过程中时,服务器不必每次执行它时都要分析和编译它。
2。调用存储过程,可以认为是一个三层结构。这使你的程序易于维护。如果程序需要做某些改动,你只要改动存储过程即可
3。你可以在存储过程中利用Transact-SQL的强大功能。一个SQL存储过程可以包含多个SQL语句。你可以使用变量和条件。这意味着你可以用存储过程建立非常复杂的查询,以非常复杂的方式更新数据库。
存储过程的能力大大增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
* 可保证数据的安全性和完整性。
# 通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。
# 通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。
* 在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执行。
* 可以降低网络的通信量。
* 使体现企业规则的运算程序放入数据库服务器中,以便:
# 集中控制。
# 当企业规则发生变化时在服务器中改变存储过程即可,无须修改任何应用程序。企业规则的特点是要经常变化,如果把体现企业规则的运算程序放入应用程序中,则当企业规则发生变化时,就需要修改应用程序工作量非常之大(修改、发行和安装应用程序)。如果把体现企业规则的运算放入存储过程中,则当企业规则发生变化时,只要修改存储过程就可以了,应用程序无须任何变化。
常用系统存储过程
sp_databases:列出服务器上的所有数据库;
sp_helpdb:报告有关指定数据库或所有数据库的信息;
sp_renamedb:更改数据库的名称;
sp_tables:返回当前环境下可查询的对象的列表;
sp_columns:回某个表列的i信息;
sp_help:查看某个表的所有信息;
sp_helpconstraint:查看某个表的约束;
sp_helpindex:查看某个表的索引;
sp_stored_procedures:列出当前环境中的所有存储过程;
sp_password:添加或修改登录账户的密码;
sp_helptext:显示默认值、未加密的存储过程、用户定义的存储过程、触发器或视图的实际文本;