plsql package - example

本文介绍了一个PL/SQL包的实现案例,包括定义过程、函数及游标的使用方法,并展示了如何从PL/SQL和JDBC中调用这些组件。

plsql package - example

 

an example to use plsql package/function/procedure of oracle,

 

include:

  • package/functipn/procedure define
  • sys_refcursor use
  • call from plsql
  • call from jdbc

------

table

 

create table customer(
	customer_id NUMBER(10),
	customer_name VARCHAR2(100),
	address varchar2(200),
	primary key(customer_id)
);

create table orders(
	order_id NUMBER(10),
	order_date DATE,
	order_name VARCHAR2(200),
	customer_id NUMBER(10),
	primary key(order_id)
);
 

------

data

 

-- customer
declare
  n CONSTANT NUMBER(4) := 5; -- row count
  i NUMBER(4);
begin
  for i in 1..n loop
	insert into customer values (i, concat('eric',i), 'shenzhen');
  end loop;
end;

-- orders
declare
  n CONSTANT NUMBER(4) := 5; -- customer row count
  i NUMBER(4);  -- customer id
  j NUMBER(2);
  order_id NUMBER(6) := 1;
begin
  for i in 1..n loop
    for j in 1..i loop
	insert into orders values (order_id, to_date('2010-3-21','YYYY-MM-DD'), concat('order_',order_id), i);
      order_id:=order_id+1;
    end loop;
  end loop;
end;
 

 

------

package

 

create or replace
PACKAGE pkg_orders_by_customer
AS
	procedure proc_orders_by_customer(p_customer_id in orders.customer_id%type, order_ref_cursor out SYS_REFCURSOR);
	function fun_order_count(p_customer_id in NUMBER) return NUMBER;
END;
  

------

package body

 

create or replace PACKAGE body pkg_orders_by_customer AS
	procedure proc_orders_by_customer(p_customer_id in orders.customer_id%type, order_ref_cursor out SYS_REFCURSOR)
	IS
	BEGIN
		open order_ref_cursor for
		select c.customer_id, o.order_id, o.order_name, o.order_date
		from customer c join orders o on c.customer_id=o.customer_id
		where o.customer_id = p_customer_id;      
	END proc_orders_by_customer;

	function fun_order_count(p_customer_id in NUMBER) return NUMBER
	IS
	order_count NUMBER;
	BEGIN
		select count(*) into order_count from orders o where o.customer_id=p_customer_id;
		return order_count;
	END fun_order_count;
END;
  

------

call function - plsql

 

set serveroutput on;

declare
  cid NUMBER(5);
  ocount NUMBER(5);
  n NUMBER(4):=5; -- customer count
begin
  for cid in 1..n loop
    ocount := pkg_orders_by_customer.fun_order_count(p_customer_id => cid);
    dbms_output.put_line('customer_id: ' || cid || ', order_count: ' || ocount);
  end loop;
end;
  

------

call procedure - plsql

 

set serveroutput on;

declare
  n NUMBER(4):=5; -- customer count
  cid NUMBER(5);
  v_cursor SYS_REFCURSOR;
  v_customer_id customer.customer_id%type;
  v_order_id orders.order_id%type;
  v_order_name orders.order_name%type;
  v_order_date orders.order_date%type;  
begin
  for cid in 1..n loop
    pkg_orders_by_customer.proc_orders_by_customer(p_customer_id => cid, order_ref_cursor => v_cursor);
    loop
      fetch v_cursor 
      into v_customer_id, v_order_id, v_order_name, v_order_date;
      EXIT WHEN v_cursor%NOTFOUND;
      dbms_output.put_line(v_customer_id || ', ' || v_order_id || ', ' || v_order_name || ', ' || v_order_date);
    end loop;
    close v_cursor;
    dbms_output.new_line();
  end loop;
end;
 

------

call function - jdbc

 

public static void functionTest() {
	try {
		Class.forName("oracle.jdbc.driver.OracleDriver");

		String url, user, password;
		url = "jdbc:oracle:thin:@localhost:1521:xe";
		user = "cumtspace";
		password = "abcdefg";

		// create connection
		Connection conn = DriverManager.getConnection(url, user, password);

		// create CallableStatement
		CallableStatement cstmt = conn.prepareCall("{?=call pkg_orders_by_customer.fun_order_count(?)}");
		cstmt.registerOutParameter(1, Types.INTEGER);
		int customer_id = 4;
		cstmt.setInt(2, customer_id);
		// execute
		cstmt.execute();
		// get out param
		Integer count = cstmt.getInt(1);
		System.out.println(customer_id + ", " + count);

		cstmt.close();
		conn.close();
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	} catch (SQLException e) {
		e.printStackTrace();
	}
}
 

------

call procedure - jdbc

 

public static void procedureTest() {
	try {
		Class.forName("oracle.jdbc.driver.OracleDriver");

		String url, user, password;
		url = "jdbc:oracle:thin:@localhost:1521:xe";
		user = "cumtspace";
		password = "abcdefg";

		// create connection
		Connection conn = DriverManager.getConnection(url, user, password);

		// create CallableStatement
		CallableStatement cstmt = conn.prepareCall("{call pkg_orders_by_customer.proc_orders_by_customer(?,?)}");

		// set in/out params
		int cid = 4;
		cstmt.setInt(1, cid);
		cstmt.registerOutParameter(2, OracleTypes.CURSOR);

		// execute
		cstmt.execute();

		// get ResultSet from out param
		ResultSet rs = (ResultSet) cstmt.getObject(2);

		// handle resultset
		int customer_id, order_id;
		String order_name;
		Date order_date;
		while (rs.next()) {
			customer_id = rs.getInt(1);
			order_id = rs.getInt(2);
			order_name = rs.getString(3);
			order_date = rs.getDate(4);

			System.out.format("%5d\t%5d\t%15s\t%s\n", customer_id, order_id, order_name, order_date);
		}

		// close
		rs.close();
		cstmt.close();
		conn.close();
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	} catch (SQLException e) {
		e.printStackTrace();
	}
}
 

------


 

### PL/SQL 中调用 Job 的方法 在 Oracle 数据库中,可以通过 `DBMS_JOB` 或者更现代的 `DBMS_SCHEDULER` 包来创建和管理后台作业(Job)。这些包提供了丰富的功能用于调度、执行以及监控各种类型的批处理任务。 #### 使用 DBMS_JOB 创建并提交一个简单的定时任务 下面是一个利用 `DBMS_JOB.SUBMIT` 过程创建新作业的例子: ```sql DECLARE job_number BINARY_INTEGER; BEGIN -- 提交一个新的job到队列中 DBMS_JOB.submit( job => job_number, what => 'BEGIN my_procedure; END;', next_date => SYSDATE, interval => 'SYSDATE + 1/24' -- 每隔一小时运行一次 ); COMMIT; dbms_output.put_line('Newly created job id is: ' || TO_CHAR(job_number)); END; / ``` 此段代码会安排名为 `my_procedure` 的存储过程每个小时被执行一次。需要注意的是,在实际应用环境中应当替换 `'BEGIN my_procedure; END;'` 为具体要执行的操作逻辑,并调整时间间隔参数以满足业务需求[^1]。 对于更为复杂的调度需求,则推荐使用 `DBMS_SCHEDULER`,因为它相比起旧版的 `DBMS_JOB` 提供了更多的特性和灵活性。 #### 利用 DBMS_SCHEDULER 实现复杂调度方案 这里展示如何通过 `DBMS_SCHEDULER.CREATE_JOB` 来设置一个按特定计划定期启动的任务实例: ```sql BEGIN DBMS_SCHEDULER.create_job ( job_name => 'example_scheduler_job', job_type => 'PLSQL_BLOCK', job_action => 'BEGIN my_package.my_function(); END;', start_date => TRUNC(SYSDATE), repeat_interval => 'FREQ=DAILY; BYHOUR=8; BYMINUTE=0; BYSECOND=0', -- 每天早上八点整执行 enabled => TRUE ); DBMS_OUTPUT.PUT_LINE ('Scheduler job has been successfully created.'); END; / ``` 上述脚本定义了一个每天上午8点钟自动触发的过程调用。同样地,这里的 `my_package.my_function()` 应当被替换成目标对象的真实名称[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值