oracle-pl/sql之二
java
触发器
包
你可以编写用户定义的函数(用pl/sql,java,c)来提供在sql中或sql内置函数中不可用的功能
有时,我们会发现有些功能通过PL/SQL完成会很麻烦,而通过C/C++语言编程则会容易很多。因此,oracle提供了在PL/SQL程序里直接调用外部函数(包括C函数或Java方法)的功能,从而扩展了PL/SQL的程序功能。
在Oracle的存储过程和函数中,其实IS和AS是同义词,没有什么区别。
还有在自定义类型(TPYE)和包(PACKAGE)时,使用IS和AS也并没有什么区别。
但是在创建视图(VIEW)时,只能使用AS而不能使用IS。
在声明游标(CURSOR)时,只能使用IS而不能使用AS。
用java的方法
例子:一个简单的需求,用Java代码实现求圆的面积,圆周率PI为3.14,输入的参数为圆的半径R,输出圆的面积S,要求可以在oracle中用PL/SQL代码调用该Java类实现求圆的面积的功能。 Step 1:编写Java代码,PL/SQL Developer本身虽然支持编写Java代码,但是毕竟不是专业的,对Java的工具提供的不是特别好,我喜欢用MyEclipse开发好以后复制过来,下面是我在MyEclipse中开发好的代码。 // 圆工具类,计算圆的面积
public class CircleTools {
// 定义常量PI
public static final double PI = 3.14; // 计算面积
public static double calcSquare(double r) {
return PI * r * r;
}
} 注意在写Java代码的时候,为了能够直接能够在oracle中被调用,所以这里在需要调用的方法前要加上public和static。 Step 2:写好Java代码,下面就是要将Java导入到oracle数据库中,
导入的方法在前文提到过可以用loadJava或者直接写。如果要用loadJava导入,先把上面的代码文件保存为CircleTools.java,然后在cmd命令行中进入该目录下,然后执行如下命令: loadjava是安装数据库自带的工具
[oracle@oracle1 ~]$ which loadjava
/u01/app/oracle/product/11.2.0/dbhome_1/bin/loadjava loadjava –u username/userpassword –v -resolve CircleTools.java 执行上面的命令就OK了,下面提供另一种方法,就是直接在PL/SQL中写,写法如下: CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED circletools AS
// 圆工具类,计算圆的面积
public class CircleTools {
// 定义常量PI
public static final double PI = 3.14;
// 计算面积
public static double calcSquare(double r) {
return PI * r * r;
}
} 查看这个数据字典发现已经进入数据库中了
select * from user_objects
where length(object_type) >5; Step 3:编写存储过程(procedure)或者函数(function)来封装,以实现以后的调用,一般来说,如果一个Java方法没有返回值,那么就封装成存储过程,如果有返回值,就封装成函数,这里我只给出一个封装成函数的例子: CREATE OR REPLACE FUNCTION calc_square(r IN NUMBER) RETURN NUMBER AS
LANGUAGE JAVA NAME 'CircleTools.calcSquare(double) return double'; Step 4:测试函数,2是半径
select calc_square(2) from dual; Step 5:如果不想用那个Java类了,可以用dropjava命令删除掉系统中的Java,这个跟loadjava很相似,
dropjava -user username/userpassword@db -v javasourcename 注意上面删除的是Java的source name,不是class name,即对象的OBJECT_TYPE是JAVA SOURCE,不是JAVA CLASS。
触发器
===============================
创建触发器
create or replace trigger test.login_log
after create or drop on schema
BEGIN
-- 以下使用的是事件属性
DBMS_OUTPUT.PUT_LINE('I believe you have created a ' ||
ORA_DICT_OBJ_TYPE || ' called ' ||
ORA_DICT_OBJ_NAME);
END;
测试触发器
set serveroutput on
CREATE TABLE "TEST"."T3"
(
"PRODUCT_ID" NUMBER,
"PRODUCT_NAME" VARCHAR2(80 BYTE),
"MONTH" NUMBER
);
drop table t3 purge;
===========================
记录登录数据库历史记录,使用触发器
建表可以在普通用户之下,但创建触发器需要在sys用户下
create table login_history
(
username varchar2(60), --用户名
machine varchar2(60), --机器名
login_time date, --登录时间
ip varchar2(50) --ip地址
);
create or replace trigger login_log
after logon on database
begin
insert into test.login_history
select username, machine, sysdate, sys_context('userenv', 'ip_address')
from v$session
where audsid = userenv('sessionid');
commit;
end;
CREATE OR REPLACE TRIGGER TRIGGER1
BEFORE DELETE OR INSERT OR UPDATE OF IP,LOGIN_TIME,MACHINE,USERNAME ON LOGIN_HISTORY
BEGIN
NULL;
END;
可用的DDL事件
DDL事件 触发时机
ALTER 对数据库中的任何一个对象使用SQL的ALTER命令时触发
ANALYZE 对数据库中的任何一个对象使用SQL的ANALYZE命令时触发
ASSOCIATE STATISTICS 统计数据关联到数据库对象时触发
AUDIT 通过SQL的AUDIT命令打开审计时触发
COMMENT 对数据库对象做注释时触发
CREATE 通过SQL的CREATE命令创建数据库对象时触发
DDL 列表中所用的事件都会触发
DISASSOCIATE STATISTICS 去掉统计数据和数据库对象的关联时触发
DROP 通过SQL的DROP命令删除数据库对象时触发
GRANT 通过SQL的GRANT命令赋权时触发
NOAUDIT 通过SQL的NOAUDIT关闭审计时触发
RENAME 通过SQL的RENAME命令对对象重命名时触发
REVOKE 通过SQL的REVOKE语句撤销授权时触发
TRUNCATE 通过SQL的TRUNCATE语句截断表时触发
可用属性
Oracle 提供了一系列的函数用来提供关于什么触发了DDL触发器以及触发器的状态灯信息。上面那个触发器的例子就使用了属性。
DDL触发器事件以及属性函数
函数名 返回值
ORA_CLIENT_IP_ADDRESS 客户端IP地址
ORA_DATABASE_NAME 数据库名称
ORA_DES_ENCRYPTED_PASSWORD 当前用户的DES算法加密后的密码
ORA_DICT_OBJ_NAME 触发DDL的数据库对象名称
ORA_DICT_OBJ_NAME_LIST 受影响的对象数量和名称列表
ORA_DICT_OBJ_OWNER 触发DDL的数据库对象属主
ORA_DICT_OBJ_OWNER_LIST 受影响的对象数量和名称列表
ORA_DICT_OBJ_TYPE 触发DDL的数据库对象类型
ORA_GRANTEE 被授权人数量
ORA_INSTANCE_NUM 数据库实例数量
ORA_IS_ALTER_COLUMN 如果操作的参数column_name指定的列,返回true,否则false
ORA_IS_CREATING_NESTED_TABLE 如果正在创建一个嵌套表则返回true,否则false
ORA_IS_DROP_COLUMN 如果删除的参数column_name指定的列,返回true,否则false
ORA_LOGIN_USER 触发器所在的用户名
ORA_PARTITION_POS SQL命令中可以正确添加分区子句位置
ORA_PRIVILEGE_LIST 授予或者回收的权限的数量。
ORA_REVOKEE 被回收者的数量
ORA_SQL_TXT 触发了触发器的SQL语句的行数。
ORA_SYSEVENT 导致DDL触发器被触发的时间
ORA_WITH_GRANT_OPTION 如果授权带有grant选项,返回true。否则false
更多属性函数请参考官方文档PL/SQL Language Reference -> Triggers and Oracle Database Data Transfer Utilities
创建触发器 CREATE OR REPLACE TRIGGER test.no_drop
BEFORE DDL ON DATABASE
BEGIN
IF ORA_SYSEVENT = 'CREATE'
THEN
DBMS_OUTPUT.PUT_LINE('Warning !!! You have created a '||
ORA_DICT_OBJ_TYPE ||' called '||
ORA_DICT_OBJ_NAME|| '; UserName(creater):'||
ORA_DICT_OBJ_OWNER||'; IP:'||
ORA_CLIENT_IP_ADDRESS||'; event:'||
ORA_SYSEVENT);
ELSIF ORA_SYSEVENT = 'DROP'
THEN
RAISE_APPLICATION_ERROR (-20000,
'Cannot create the ' || ORA_DICT_OBJ_TYPE ||
' named ' || ORA_DICT_OBJ_NAME ||
' as requested by ' || ORA_DICT_OBJ_OWNER);
END IF;
END; 测试触发器
set serveroutput on
CREATE TABLE "TEST"."T4"
(
"PRODUCT_ID" NUMBER,
"PRODUCT_NAME" VARCHAR2(80 BYTE),
"MONTH" NUMBER
);
drop table t4 purge;
package包的使用
SET SERVEROUTPUT ON SIZE 40000
DECLARE
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
value VARCHAR2(1024);
BEGIN
--UTL_HTTP.SET_PROXY('proxy.my-company.com', 'corp.my-company.com');
req := UTL_HTTP.BEGIN_REQUEST('http://www.ka1che.com');
UTL_HTTP.SET_HEADER(req, 'User-Agent', 'Mozilla/4.0');
resp := UTL_HTTP.GET_RESPONSE(req);
LOOP
UTL_HTTP.READ_LINE(resp, value, TRUE);
DBMS_OUTPUT.PUT_LINE(value);
END LOOP;
UTL_HTTP.END_RESPONSE(resp);
EXCEPTION
WHEN UTL_HTTP.END_OF_BODY THEN
UTL_HTTP.END_RESPONSE(resp);
END;
==================================================
http://blog.csdn.net/ls_man/article/details/11981967
创建过程来自动杀死相关session
GRANT create view to PERSONAL;
grant alter system to personal;
create view mysession as
select SID,SERIAL# from v$session
where schemaname in ('TEST1','TEST2');
create user test1 identified by 123456;
create user test2 identified by 123456;
grant connect,resource to test1,test2;
create or replace procedure kill_session is
v_sid varchar2(30);
v_serial varchar2(30);
v_sql varchar2(1000);
TYPE DyData IS REF CURSOR;
rows DyData;
begin
v_sql := 'select * from mysession ';
OPEN rows FOR v_sql;
LOOP
FETCH rows
into v_sid, v_serial;
v_sql := 'alter system kill session ''' || v_sid || ',' || v_serial || '''';
execute immediate v_sql;
--dbms_output.put_line(v_userid || '__' || v_user || '__' || v_pwd);
EXIT WHEN rows%NOTFOUND;
END LOOP;
end kill_session;
======================================
Oracle wrap 和 unwrap( 加密与解密) 说明
http://blog.chinaunix.net/uid-7589639-id-3767585.html
wrap 的使用步骤如下:
(1)将我们要加密的sql 语句保存到一个sql文本里。
(2)用wrap 进行处理,指定输入的sql,即我们第一步的问题,然后指定输出的路径和文件名,默认扩展名是plb。
(3)执行我们第二步进过wrap 处理的sql,即plb文件,创建我们的对象.
命令行界面
cat dave.sql
wrap iname=dave.sql
cat dave.plb
sqlplus界面
@dave.plb
select F_DAVE(4) from dual;
select text from dba_source where name='F_DAVE';
wrap的目的是为了加密,所以Oracle并没有提供unwrap 的方法。 itpub上的一些牛人研究了一下这个问题,写了一些unwrap的代码。 具体讨论的过程,参考itpub的2个帖子:
阿里巴巴的张端弄了一个界面的Unwrap软件,下载地址:
oracle-pl/sql之二的更多相关文章
- 二十二、oracle pl/sql分类二 函数
函数用于返回特定的数据,当建立函数时,在函数头部必须包含return子句.而在函数体内必须包含return语句返回的数据.我们可以使用create function来建立函数. 1).接下来通过一个案 ...
- [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功)
原文:[顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [顶]ORACLE PL/SQL编程详解之二: PL/SQL块结构和组成元素(为山九仞,岂一日 ...
- ORACLE PL/SQL编程详解
ORACLE PL/SQL编程详解 编程详解 SQL语言只是访问.操作数据库的语言,并不是一种具有流程控制的程序设计语言,而只有程序设计语言才能用于应用软件的开发.PL /SQL是一种高级数据库程序设 ...
- [强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!)
原文:[强烈推荐]ORACLE PL/SQL编程详解之七:程序包的创建与应用(聪明在于学习,天才在于积累!) [强烈推荐]ORACLE PL/SQL编程详解之七: 程序包的创建与应用(聪明在于学习,天 ...
- ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!)
原文:ORACLE PL/SQL编程之六:把过程与函数说透(穷追猛打,把根儿都拔起!) ORACLE PL/SQL编程之六: 把过程与函数说透(穷追猛打,把根儿都拔起!) 继上篇:ORACLE P ...
- [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)
原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...
- [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到)
原文:[推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之四: 把游标说透(不怕做不到,只怕想不到) 继上两篇:ORACLE PL ...
- 【强烈强烈推荐】《ORACLE PL/SQL编程详解》全原创(共八篇)--系列文章导航
原文:[强烈强烈推荐]<ORACLE PL/SQL编程详解>全原创(共八篇)--系列文章导航 <ORACLE PL/SQL编程详解> 系列文章目录导航 ——通过知识共享树立个人 ...
- [推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下)
原文:[推荐]ORACLE PL/SQL编程详解之一:PL/SQL 程序设计简介(千里之行,始于足下) [推荐]ORACLE PL/SQL编程详解之一: PL/SQL 程序设计简介(千里之行,始于足下 ...
- ORACLE PL/SQL编程详解(转)
原帖地址:http://blog.csdn.net/chenjinping123/article/details/8737604 ORACLE PL/SQL编程详解 SQL语言只是访问.操作数据库的语 ...
随机推荐
- 「版本升级」MyEclipse CI 2018.12.0正式发布
新版本MyEclipse为WildFly 14新增一个新的服务器连接器,改进性能并新增一些Java 10修复程序.新版本为IDE做了几个核心修复,这是MyEclipse 2018一个更棒的升级. [M ...
- Ajax 以及 前端JSP页面如何查看数值
$.ajax({ url: ctx + "/unit/rsdl/qyjy/getDljgCode", type: "post", success: functi ...
- day 26面向对象 的封装 接口 抽象
大纲分析 # 面向对象# 类 :一类具有相同属性和方法的事物 #类的定义:class #类中可以定义的方法种类: #普通方法 self 对象 #类方法 cls @classmethod 类/对象 #静 ...
- 转-Asynchronous bulk transfer using libusb
https://falsinsoft.blogspot.jp/2015/02/asynchronous-bulk-transfer-using-libusb.html The 'linusb' is ...
- chromium ⑤
我们都知道chromium是用webkit完成页面显示的, 那么chromium是怎样集成和封装webkit的呢? 是怎样将webkit整合到自己的框架中,并将一个页面渲染出来的? 这篇我 ...
- mysql主从复制-读写分离
mysql主从复制+读写分离 环境:mysql主:193.168.1.1mysql从:193.168.1.2amoeba代理:193.168.1.3########################## ...
- 大数据-08-Sqoop入门
简介 Sqoop是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql.postgresql-)间进行数据的传递,可以将一个关系型数据库(例如 : MySQL ,Oracle ...
- Android反调试笔记
1)代码执行时间检测 通过取系统时间,检测关键代码执行耗时,检测单步调试,类似函数有:time,gettimeofday,clock_gettime. 也可以直接使用汇编指令RDTSC读取,但测试AR ...
- Java中的break和continue以及标签
一.Java中的break,continue,goto 首先break,continue是Java中的关键字,而goto是保留字. 基于goto在c和c++中的鬼畜表现,我觉得goto可能还会长期在J ...
- Gym-101673 :East Central North America Regional Contest (ECNA 2017)(寒假自训第8场)
A .Abstract Art 题意:求多个多边形的面积并. 思路:模板题. #include<bits/stdc++.h> using namespace std; typedef lo ...