??xml version="1.0" encoding="utf-8" standalone="yes"?> -- / 斜线回R --调用存储q程 --------- 下面以输入员工号Q显C雇员名U、工资、个人所得税(E率?.03Z)。说明变量的使用Q看看如何编写: declare declare --定义了一个sp_record变量Q类型是emp_record_type begin --循环取出 ---------- ---- --------------- create or replace procedure sp_pro8(ename in numberQspName out varchar2) is Q-Q-Q-Q-Q-Q- ~写oracle的分? --计算myrows --关闭游标 ------------------------------------------------ ------------------------------------------------ }catch(Exception e) ------------------------------------------------ }catch(Exception e) A . 嵌套? 1. 声明数组cd 2. 创徏存储q程 3. Java调用代码 B . 索引?
<!-- 从jdbc:oracle:thin:@10.128.5.65:1521:tjgwl1 中蟩?服务器间跌{)
10.128.141.109:1521:tjgwlw数据库后面直接加@tjgwlw-->
]]>
]]>
]]>
--create procedure 存储q程名字 is begin
--create or replace procedure 如果有就替换?br />----------------------------------------------
案例1Q?br />--创徏一个表
create table mytest(name varchar2(30),passwd varchar2(30));
--创徏q程
create procedure sq_pro1 is
begin
--执行部分
insert into mytest values('zgx','888666');
endQ?/p>
----------------------------------------------
如何查看错误信息Q?br />show error 回R
1.exec q程?参数1Q?....);
2.call q程?参数1Q?....);
---------------------------------------------------
set serveroutput on;打开输出选项
set serveroutput off;关闭输出选项
dbms_ 是包名的意思!
案例2Q?br />dbms_output.put_line('helloWorld');
-----------------
declare
v_ename varchar2(5);--定义字符串变?br />begin
--into v_ename意?把查询出来数?赋值给 v_ename;&no是执行的时候会弹出输入?br /> select ename into v_ename from emp where empno=&no;
--||代表 q接W号Q?br /> dbms_output.put_line('用户名是Q?||v_ename);
end;
-----------
案例3Q?br />declare
v_ename varchar2(5);--定义字符串变?br /> v_sal number(7,2);--定义字符串变?br />begin
--如果是多个字D,用逗号隔开Q顺序必MPQ?br /> select ename,sal into v_ename,v_sal from emp where empno=&no;
--||代表 q接W号Q?br /> dbms_output.put_line('用户名是Q?||v_ename||'工资Q?||v_sal);
end;
---------------------
--异常的捕?br />exception
when no_data_found then --如果出现no_data_found异常执行下一?br />dbms_output.put_line('输入有误Q?);
end;
------------
q程Q?br />案例4Q?br />创徏带输入参数的q程Q?br />create procedure sp_pro3(spNma varchar2,newSal number) is
begin
update emp set sal=newSal where ename=spName;
end;
------------
函数Q?br />函数用于q回特定的数据,当徏立函数时Q在函数头部要求有return语句Q?br />案例5Q?br />--输入雇员姓名Q返回该雇员的年?br />--q回一个numbercdQ返回值名字是yearSalQ类型是number(7,2);
create function sp_fun1(spName varchar2) return number is yearSal number(7,2);
begin
--执行部分
select sal*12+nvl(comm,0)*12 into yearSal from emp where enamee=spName;
return yearSal;
end;
调用函数?br />--随便定义一个?br />var abc number;
--掉用函数把结果赋值给 abc
call sp_fun1()'SCOTT' into:abc;
-------------
?br />创徏包:
--创徏了一个包 sp_package
--声明该包里有一个过Eupdate_sal
--生命该包里有一个函数annual_income
create package sp_package is
procedure update_sal(name,varchar2,newsal number);
function annual_income(name varchar2, return number;
end;
l包sp_package 实现包体--把定义包中的 q程和函数实玎ͼ
create package body sp_package is
procedure update_sal(name,varchar2,newsal number) is
begin
update emp set sal=newsal where ename=name;
end;
function annual_income(name varchar2)
return number isannual_salary number;
begin
select sal*12+nvl(comm,0) into annual_salary from emp where ename=name;
return annual_salary;
end;
end;
--------------
调用包中的过E或函数
exec sp_package.update_sal('SCOTT','120');
---------------------
触发?br />触发器是指隐含的执行的存储过E。当定义触发器时Q必要指定触发的时间和触发的操作,常用触发包括insertQpudateQdelete语句Q而触发操作实际就是一个pl/sql块。可以用create trigger来徏立触发器?br />触发器是非常有用的,可维护数据库的安全和一致性?br />---------
定义q用变?br />包括Q?br />1.标量cdQscalarQ?br />2.W合cdQ)
标量QscalarQ?常用cd
语法Q?br />identifier [constant] datatype [not null] [:=| default expr]
identifier:名称
constantQ指定常量。需要指定它的初始|且其值是不能改变?br />datatypeQ数据类?br />not nullQ?指定变量g能ؓnull
Q? l变量或是常量指定初始?br />default 用于指定初始?br />exprQ指定初始值的pl/sql表达式,文本倹{其他变量、函数等
------------
标量定义的案?br />1.定义一个变长字W串
v_ename varchar2(10)
2.定义一个小?范围 -9999.99~9999.99
v_sal number(6,2)
3.定义一个小数ƈl一个初始gؓ5.4 :=pl/sql的赋值号
v_sal2 number(6,2):=5.4
4.定义一个日期类型的数据
v_hiredate date;
5.定义一个布?yu)变量,不能为空Q初始gؓfalse
v_valid boolean not null default false;
---------------
如何使用标量
定义好变量后Q就可以使用q些变量。这里需要说明的是pl/sql块ؓ变量赋g同于其他的编E语aQ需要在{号前面加冒?:=)
c_tax_rate number(3.2):=0.03; --定义赋?br />--用户?br />v_ename varchar2(5);
v_sal number(7,2);
v_tax_sal number()7,2;
begin
--执行
select ename,sal into v_ename,v_sal from emp where empno=$no;
--计算所得税
v_tax_sal:=v_sal*c_tax_rate;
--输出
dbms_output.put_line('姓名?'||v_ename||'工资Q?||v_sal||'所得税Q?||v_tax_sal);
end;
-----
标量QscalarQ?-使用%typecd
对于上面的pl/sql块有一个问题:
是如果员工的姓名超q了5字符的话Q就会有错误Qؓ了降低pl/sqlE序的维护工作量Q可以?type属性定义变量,q样他会按照数据库列来确定你定义的变量的cd和长度?br />看看怎么使用?br />语法Q?标识W名 表名.列名%type;
v_ename emp.ename%type; --定义变量v_ename 和emp表中列名ename大小cd保持一_
---
复合变量QcompositeQ?br />用于存放多个值的变量?br />包括Q?br />1.pl/sql记录
2.pl/sql?br />---------------
复合cd-pl/sql记录
cM与高U语a的结构体Q需要注意的是,当引用pl/sql记录成员Ӟ必须要加记录变量作ؓ前缀Q记录变?记录成员Q?br />如下Q?br />declare
--定义一个pl/sql记录cd是:emp_record_typeQ类型包括三个数据nameQsalaryQtitleQ该cd中可以存放三个类型的数据Q?br />type emp_record_type is record(name emp.ename%type,salary emp.sal%type,title emp.job%type);
sp_record emp_record_type;
select ename,sal,job into sp_record from emp where empno=7788;
dbms_output.put_line('员工名:'||sp_record.name); --昄定义emp_record_typecd?name的|
end;
end;
----------------
复合cd--pl/sql?br /> 相当于高U语a中的数组。但是需要注意的是在高语言中数l的下标不能敎ͼ而pl/sql是可以ؓ负数的,q且表元素的下标没有限制。实例如下:
declare
--定义了一个pl/sql表类型sp_table_typeQ该cd是用于存放emp.ename%typecd的数l?br />--index by binary_integer标识下标是整?br />type sp_table_type is table of emp.ename%type index by binary_integer;
--定义了一个sp_table变量Q变量类型是sp_table_type
sp_table sp_table_type;
begin
--把查询出来的ename攑ֈ tableQ?Q下标ؓ0的数?br />select ename into sp_table(0) from emp where empno=7788;
dbms_output.put_lin('员工名:'||sp_table(0)); --要和存放下标一?br />end;
说明Q?br />sp_table_type 是pl/sql表类?br />emp.ename%type 指定了表的元素的cd和长?br />sp_table 为pl/sql表变?br />sp_table(0) 表示下标??br />---------------
参照变量
参照变量是指用于存放数值指针的变量。通过使用参照变量Q可以用得应用E序׃n相同对象Q从而降低占用的I间。在~写pl/sqlE序Ӟ可以使用游标变量和对象类型变量两U参照变量类?br />游标变量用的最?br />-----------
参照变量---游标变量
使用游标Ӟ当定义游标时不需要指定相应的select语句Q但是当使用游标旉要指定select语句Q这样一个游标就与一个select语句l合了?br />如下
1.请用pl/sql~写一个块Q可以输入部门号Qƈ昄该部门所有员工姓名和他的工资?br />declare
--定义游标cd
type sp_emp_cursor is ref cursorQ?br /> --定义一个游标变?br /> test_cursor sp_emp_cursorQ?br /> --定义变量
v_ename emp。ename%typeQ?br /> v_sal emp。sal%typeQ?br />begin
--执行
--打开一个游标test_cursor和一个selectl合
open test_cursor for select ename,sal from emp where deptno=&no;
--循环取出
loop
--fetch是取出。取出test_cursor中的数据攑ֈ v_ename,v_sal里面去;
fetch test_cursor into v_ename,v_salQ?br /> --判断是否test_cursor为空
exit when test_cursor%notfoundQ?br /> dbms_output.put_line('名字Q?||v_ename||'工资Q?||v_sal);
end loopQ?br />endQ?/p>
2.?。基上,如果某个员工的工资低?00元,增?00元?br />declare
--定义游标cd
type sp_emp_cursor is ref cursorQ?br /> --定义一个游标变?br /> test_cursor sp_emp_cursorQ?br /> --定义变量
v_ename emp。ename%typeQ?br /> v_sal emp。sal%typeQ?br />begin
--执行
--打开一个游标test_cursor和一个selectl合
open test_cursor for select ename,sal from emp where deptno=&no;
loop
--fetch是取出。取出test_cursor中的数据攑ֈ v_ename,v_sal里面去;
fetch test_cursor into v_ename,v_salQ?br /> if v_sal<200 then
update emp set sal=sal+100 where ename=v_ename;
end if;
--判断是否test_cursor为空
exit when test_cursor%notfoundQ?br /> dbms_output.put_line('名字Q?||v_ename||'工资Q?||v_sal);
end loopQ?br />endQ?/p>
条g分支语句
if--thenQ?br />if--then--elseQ?br />if--then--elsif--else
循环语句
loop --end loopQ至会执行一ơ?br />create or replace procedure sp_pro6() is
--定义赋?br />v_num number:=1;
begin
loop
insert into users1 values(v_num,spName);
--判断是否要退出@?br /> exit when v_num=10;
--自增
v_num:=v_num+1;
end loop;
end;
-------------
循环语句-while先判断后执行
create or replace procedure sp_pro6() is
--定义赋?br />v_num number:=11;
begin
while v_num<=20 loop
insert into users1 values(v_num,spName);
v_num:=v_num+1;
end loop;
end;
------------------
循环语句--for循环Q不Q?br />begin
for i in reverse 1。?0 loop
insert into users1 valuesQiQ?aaa'Q;
end loop;
endQ?br />-------
循环语句--goto,null循环Q不Q?br />declare
i int:=1;
begin
loop
dbms_output.put_line('输出i='||i);
if i=10 then
goto end_loop;
end if;
i:=i+1;
end loop;
<<end_loop>> --到i?0后直接蟩到该标记
dbms_output.put_line('循环l束');
end;
---------------------------
无返回值的存储q程Q有输入参数Q?br />
create table book(
bookId number;
bookName varchar2(100);
publishHouse varchar2(50);
);
--~写q程
--in表示q是一个输入参敎ͼ不写默认是in
--out 表示一个输出参?br />create or replace procedure sp_pro7(spBookId in numberQspbookName in varchar2,sppublishHouse in varchar2) is
begin
insert into book values(spBookId,spbookName,sppublishHouse);
end;
有返回值的存储q程Q有输入和输出参敎ͼ
begin
--spName自动q回 因ؓ他是out
select ename into spName from emp where empno=spno;
end;
----------------
有返回值是集合数组的存储过E(有输入和输出参数Q?br />1.建立一个包
--创徏?里面定义一个游标类型;
create or replace package testpackage as
type test_cursor is ref cursor;
end testpackageQ?br />2.建立存储q程?br />create or replace procedure sp_pro8(spNo in numberQp_cursor out testpackage.test_cursor) is
begin
--spName自动q回 因ؓ他是out
open p_cursor for select * from emp where deptno=spNo;
end;
oracle的分?nbsp; rn是别?br />select t1.*Qrownum rn from(select * from emp) t1;//多加一个列记录个数
select t1.*Qrownum rn from(select * from emp) t1 where rownum<10;
select * from (select t1.*Qrownum rn from(select * from emp) t1 where rownum<10) where rn>=6;
--建立一个包
create or replace package testpackage as
type test_cursor is ref cursor;
end testpackageQ?br />--建立存储q程
create or replace procedure fenye
(tableName in varchar2,
pageSize in number, --一|C几条记?br />pageNow in number, --昄哪一?br />myrows out number, --总记录数
myPageCount out number,--总页?br />p_cursor out testpackage.test_cursor --q回的记录集
) is
--定义部分
--定义sql语句 字符?br />v_sql varchar2(1000);
--定义两个整数
v_begin number:=(pageNow-1)*pageSize+1;
v_end number:=pageNow*pageSize;
begin
--执行部分
v_sql:='select * from (select t1.*Qrownum rn from(select * from '||tableName||') t1 where rownum<10'||?||') where rn>='||?||';';
--把游标和sql语句兌h
open p_cursor for v_sql;
v_sql:='select count(*) from '||tableName||'';
--执行sqlQƈ把返回|赋值给myrows;
execute immediate v_sql int myrows;
--计算myPagecount
if mod(myrows,pageSize)=0 then --mod()取余?br />myPageCount:=myrows/pageSize;
else
myPageCount:=myrows/pagesize+1;
end if;
--close p_cursor;
end;
------------------------
例外的分c?br />1.预定义例外用于处理常见的oracle错误
2.非预定义例外用于处理预定义例外不能处理的例外 6.53
3.自定义例外用于处理与oracle错误无关的其他情?/p>
------------------------------------------------
-----------------------------------------------
-------QAQӞ?调用无返回值的存储q程-----------------
try{
Class.forName();
Connection ct=DriverManager.getConnerction();
//调用无返回值存储过E?br /> CallableStatement cs=ct.prepareCall("{call 存储q程名称(?,?,?)}") // ?代表存储q程参数
cs.setIn(1,10);
cs.setString(2,'java调用存储q程');
cs.setString(3,'人民出版C?);
//执行
cs.execute();
}catch(Exception e)
{
e.printStackTrace();
}finally{
cs.close();
ct.close();
}
-----------------------------------------------
------QAQӞ?-调用有回值的存储q程-----------------
try{
Class.forName();
Connection ct=DriverManager.getConnerction();
//调用有返回值存储过E?br /> CallableStatement cs=ct.prepareCall("{call 存储q程名称(?,?)}") // ?代表存储q程参数 W一是输入,W二是输?br /> //W一?输入参数
cs.setIn(1,10);
//l第二个Q输出D?br /> cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR); //
//执行
cs.execute();
//取出q回?
String name=cs。getString(2);
System.out。println("名称是:"+name);
}catch(Exception e)
{
e.printStackTrace();
}finally{
cs.close();
ct.close();
}
-----------------------------------------------
-------QAQӞ?调用有回值是多个 数组2011-12-5的存储过E?----------------
try{
Class.forName();
Connection ct=DriverManager.getConnerction();
//调用有返回值存储过E?br /> CallableStatement cs=ct.prepareCall("{call 存储q程名称(?,?)}") // ?代表存储q程参数 W一是输入,W二是输?br /> //W一?输入参数
cs.setIn(1,10);
//l第二个Q输出D?br /> cs.registerOutParameter(2,oracle.jdbc.OracleTypes.cursor); //cd是cursor游标
//执行
cs.execute();
//取出q回|l果集)
ReaultSet rs=(ResultSet)cs.getObject(2); //2是第二?
while(rs.next())
{
int =rs。getInt(1);
String name=rs。getString(2);
System.out。println("名称是:"+name);
}
{
e.printStackTrace();
}finally{
cs.close();
ct.close();
}
------------------------------------------------
-----------------------------------------------
------QAQӞ?-调用有回值的存储q程-----------------
try{
Class.forName();
Connection ct=DriverManager.getConnerction();
//调用有返回值存储过E?br /> CallableStatement cs=ct.prepareCall("{call 存储q程名称(?,?)}") // ?代表存储q程参数 W一是输入,W二是输?br /> //W一?输入参数
cs.setIn(1,10);
//l第二个Q输出D?br /> cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR); //
//执行
cs.execute();
//取出q回?
String name=cs。getString(2);
System.out。println("名称是:"+name);
}catch(Exception e)
{
e.printStackTrace();
}finally{
cs.close();
ct.close();
}
-----------------------------------------------
-------QAQӞ?试分页调用存储q程-----------------
try{
Class.forName();
Connection ct=DriverManager.getConnerction();
//调用有返回值存储过E?br /> CallableStatement cs=ct.prepareCall("{call 分页存储q程名称(?,?,?,?,?,?)}") // ?代表存储q程参数 W一是输入,W二是输?br /> //?输入参数
cs.setString(1,'表名'); //表名
cs.setInt(2,5); //一|C几条记?br /> cs.setInt(3,1); //昄W几?br /> //?输出参数
//注册总记录数
cs.registerOutParameter(4,oracle.jdbc.OracleTypes.INTEGER);
//注册总页?br /> cs.registerOutParameter(4,oracle.jdbc.OracleTypes.INTEGER);
//注册q回的结果集
cs.registerOutParameter(4,oracle.jdbc.OracleTypes.CURSOR); //cd是cursor游标
//执行
cs.execute();
//取出总记录数
int rowNum=cs.getInt(4);//4表示参数中第四个Q?br /> //总页?br /> int pageCount=cs.getInt(5);
//q回的记录结?br /> ReaultSet rs=(ResultSet)cs.getObject(6);
while(rs.next())
{
int =rs。getInt(1);
String name=rs。getString(2);
System.out。println("名称是:"+name);
}
{
e.printStackTrace();
}finally{
cs.close();
ct.close();
}
create or replace type tab_array is table of varchar2(38);暂时不要在包中声明该cd
-- 该例子存储过E是在包中创建的,包名 arraydemo
procedure testArray(resNumber in tab_array,procResult out tab_array) is
begin
procResult := new tab_array();
for i in 1..resNumber.Count loop
procResult.EXTEND;
procResult(i) := resNumber(i) || 'lucifer' || i;
end loop;
end;
//必须使用Oracle的连接和Statement,使用了连接池的必通过一些方法获取原始的q接
OracleConnection conn = null;
OracleCallableStatement stmt = null;
String[] param = { "1001", "1002", "1006" };
stmt =(转换cd) conn.prepareCall("{call arraydemo.testArray(?,?)}");
// cd名必d?
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("TAB_ARRAY", conn);
stmt.setARRAY(1, new ARRAY(descriptor,conn,param));
stmt.registerOutParameter(2, OracleTypes.ARRAY, "TAB_ARRAY");
stmt.execute();
ARRAY array = stmt.getARRAY(2);
Datum[] data = array.getOracleArray();
for (int i = 0; i < data.length; i++) {
System.out.println(i + " : " + new String(data.shareBytes()));
}
4 . 注意的问题及未解决的问?
抛出:Non supported character set: oracle-character-set-852 异常---解决:d nls_charset12.jar 到classpath,该包在oracle/ora92/jdbc/lib目录?
待解决问?
a) 如何调用在包声明的自定义cd
b) 比较不同声明cd的优~点,及用场?
嵌套表其它应?http://zhouwf0726.itpub.net/post/9689/212253
C . 内置数组
D . 游标方式
]]>
<script type="text/javascript">
//<![CDATA[
//嵌入CDATAD可以防止不兼容Javacript的浏览器不生错误信?br /> //增加正则表达?span class="Apple-converted-space">
String.prototype.getQueryString = function(name) {
var reg = new RegExp("(^|&|\\?)" + name + "=([^&]*)(&|$)"), r;
if (r = this.match(reg)) return unescape(r[2]);
return null;
};
var address = location.search.getQueryString("address"); //通过表达式获得传递参?br /> //针对两种览器,分别获取xmlDocument对象// dXML文g
function loadXML(xmlFile) {
var xmlDoc;
if (window.ActiveXObject) {
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = false;
xmlDoc.load(xmlFile);
}
else if (document.implementation && document.implementation.createDocument) {
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = false;
xmlDoc.load(xmlFile);
} else {
alert('(zhn)的览器不支持该系l脚本!');
}
return xmlDoc;
}
//调用地图
var map; //全局GMap GOOGLE 地图 API
function load() {
if (GBrowserIsCompatible()) //查浏览器兼容?br /> {
map = new GMap2(document.getElementById("map")); //地图加栽到ID为map的DIV中?br /> map.addControl(new GSmallMapControl()); //dGcontrol控g//攑֤~小的那?br /> map.setCenter(new GLatLng(26.577014, 104.877977), 15); //讄地图中心
//创徏多个坐标点(从INFO.XML文g中读取)
var xmlDoc = loadXML("Info.xml");
var members = xmlDoc.getElementsByTagName("number");
var maxRes = members.length;
for (var i = 0; i <= maxRes; i++) { //XML中记录了多个坐标点,要每个点都标C?br /> var oName = members[i].getElementsByTagName("name");
var oLongitude = members[i].getElementsByTagName("Longitude");
var oLatitude = members[i].getElementsByTagName("Latitude");
var name = oName[0].firstChild.nodeValue
var Longitude = oLongitude[0].firstChild.nodeValue
var Latitude = oLatitude[0].firstChild.nodeValue
var marker = new GMarker(new GLatLng(Longitude, Latitude), { title: name }); //Ҏ(gu)个点d标记
marker.openInfoWindowHtml("<div style=line-height:20px;text-align:center;font-size:12px;'><a href=Left.aspx?info=" + name + " target=framLeft>" + name + ",点击查看信息</a></div>");
map.addOverlay(marker);
}
}
}
//]]>
</script>
XML文g
<?xml version="1.0" encoding="GB2312"?>W二步是要修?mysql 的配|文?/etc/mysql/my.cnf
在旧版本中找?skip-networkingQ把它注释掉可以了
#skip-networking
在新版本中:
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 127.0.0.1
bind-address = 127.0.0.1 q一行要注释?br style="line-height: 25px" />#bind-address = 127.0.0.1
或者把允许讉K的ip 填上
bind-address = 192.168.1.100
然后重启 MySQL
/etc/init.d/mysql restart
以上Ҏ(gu)只完成了外网讉K的配|,它只允许从主Z讉KMYSQLQ如果要完全从外|访问则需要将L?306端口映射到虚拟机?306上(当然其它的端口也是可以的Q?/p>
虚拟机端口映?
http://wenku.baidu.com/view/b01c2ccca1c7aa00b52acb62.html###
create sequence member_SEQ
minvalue 1
maxvalue 9999999
start with 21
increment by 1
cache 20;
CREATE OR REPLACE TRIGGER "member_trig"
BEFORE INSERT ON admin
REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW
DECLARE
BEGIN
SELECT member_seq.NEXTVAL INTO :NEW.ID FROM DUAL;
END member_trig;