溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Oracle 存儲過程學習筆記

發(fā)布時間:2020-08-15 13:45:35 來源:ITPUB博客 閱讀:213 作者:達芬奇的夢 欄目:建站服務器

商業(yè)規(guī)則和業(yè)務邏輯可以通過程序存儲在Oracle中,這個程序就是存儲過程。 

存儲過程是SQL, PL/SQL, Java 語句的組合,它使你能將執(zhí)行商業(yè)規(guī)則的代碼從你的應用程序中移動到數(shù)據(jù)庫。這樣的結果就是,代碼存儲一次但是能夠被多個程序使用

要創(chuàng)建一個過程對象(procedural object),必須有 CREATE PROCEDURE 系統(tǒng)權限。如果這個過程對象需要被其他的用戶schema 使用,那么你必須有 CREATE ANY PROCEDURE 權限。執(zhí)行 procedure 的時候,可能需要excute權限。或者EXCUTE ANY PROCEDURE 權限。如果單獨賦予權限,如下例所示:  

grant  execute on MY_PROCEDURE  to Jelly

調用一個存儲過程的例子: 

execute MY_PROCEDURE( 'ONE PARAMETER');

存儲過程(PROCEDURE)函數(shù)(FUNCTION)的區(qū)別。 

function有返回值,并且可以直接在Query中引用function和或者使用function的返回值。

本質上沒有區(qū)別,都是 PL/SQL 程序,都可以有返回值。最根本的區(qū)別是 存儲過程是命令,  而函數(shù)是表達式的一部分。比如

select max(NAME) FROM

但是不能 exec max(NAME) 如果此時max是函數(shù)。

PACKAGEfunction,procedure,variables sql 語句的組合。package允許多個procedure使用同一個變量和游標。

創(chuàng)建 procedure的語法

 

CREATE [ OR REPLACE ] PROCEDURE [ schema.]procedure

  [(argument [IN | OUT | IN OUT ] [NO COPY] datatype

    [, argument [IN | OUT | IN OUT ] [NO COPY] datatype]...

  )]

[ authid { current_user | definer }] 

{ is | as } { pl/sql_subprogram_body | 

language { java name 'String' | c [ name, name] library lib_name

}]

Sql 代碼:

CREATE PROCEDURE sam.credit (acc_no IN NUMBER, amount IN NUMBER) AS     

   BEGIN   

      UPDATE accounts     

      SET balance = balance + amount     

      WHERE account_id = acc_no;     

   END;  

可以使用 create or replace procedure 語句, 這個語句的用處在于,你之前賦予的excute權限都將被保留。

IN, OUT, IN OUT用來修飾參數(shù)。

IN 表示這個變量必須被調用者賦值然后傳入到PROCEDURE進行處理。

OUT 表示PRCEDURE 通過這個變量將值傳回給調用者。

IN OUT 則是這兩種的組合。

authid代表兩種權限:

定義者權限(difiner right 默認),執(zhí)行者權限(invoker right)。

定義者權限說明這個procedure中涉及的表,視圖等對象所需要的權限只要定義者擁有權限的話就可以訪問。

執(zhí)行者權限則需要調用這個 procedure的用戶擁有相關表和對象的權限。

Oracle存儲過程的基本語法

1. 基本結構

CREATE OR REPLACE PROCEDURE 存儲過程名字
(
    參數(shù)1 IN NUMBER,
    參數(shù)2 IN NUMBER
AS
變量1 INTEGER :=0;
變量2 DATE;
BEGIN

END 存儲過程名字

2. SELECT INTO STATEMENT

select查詢的結果存入到變量中,可以同時將多個列存儲多個變量中,必須有一條
  記錄,否則拋出異常(如果沒有記錄拋出NO_DATA_FOUND)

例子:

BEGIN
  SELECT col1,col2 into 變量1,變量2 FROM typestruct where xxx;
  EXCEPTION
  WHEN NO_DATA_FOUND THEN
      xxxx;

 WHEN OTHERS THEN

   xxxx;
  END;
  ...

3. IF 判斷

IF V_TEST=1 THEN
    BEGIN 
       do something
    END;
  END IF;

4. while 循環(huán)

WHILE V_TEST=1 LOOP
  BEGIN
 XXXX
  END;
  END LOOP;

5. 變量賦值

V_TEST := 123;

6. for in 使用cursor

...
  IS
  CURSOR cur IS SELECT * FROM xxx;
  BEGIN
 FOR cur_result in cur LOOP
  BEGIN
   V_SUM :=cur_result.列名1+cur_result.列名2
  END;
 END LOOP;
  END;

7. 帶參數(shù)的cursor

CURSOR C_USER(C_ID NUMBER) IS SELECT NAME FROM USER WHERE TYPEID=C_ID;
  OPEN C_USER(變量值);
  LOOP
 FETCH C_USER INTO V_NAME;
 EXIT FETCH C_USER%NOTFOUND;
    do something
  END LOOP;
  CLOSE C_USER;

8. pl/sql developer debug

  連接數(shù)據(jù)庫后建立一個Test WINDOW
  在窗口輸入調用SP的代碼,F9開始debug,CTRL+N單步調試

9. Pl/Sql中執(zhí)行存儲過程

sql*plus中:

  declare   
      --必要的變量聲明,視你的過程而定   
  begin   
      execute   yourprocudure(parameter1,parameter2,...);   
  end   
  /   

   SQL/PLUS中調用存儲過程,顯示結果:  

  SQL>set serveoutput on    --打開輸出

  SQL>var info1 number;     --輸出1  

  SQL>var info2 number;     --輸出2  

  SQL>declare  

          var1  varchar2(20);       --輸入1  

          var2  varchar2(20);     --輸入2  

          var3  varchar2(20);       --輸入2  

          BEGIN  

              pro(var1,var2,var3,:info1,:info2);  

          END;  

          /  

  SQL>print  info1;  

  SQL>print  info2;

注:EXECUTE IMMEDIATE STR語句是SQLPLUS中動態(tài)執(zhí)行語句,它在執(zhí)行中會自動提交,類似于DPFORMS_DDL語句,在此語句中str是不能換行的,只能通過連接字符"||",或著在在換行時加上"-"連接字符。 

關于Oracle存儲過程的若干問題備忘

1. Oracle中,數(shù)據(jù)表別名不能加as

如:

select a.appname from appinfo a;-- 正確
select a.appname from appinfo as a;-- 錯誤

 也許,是怕和Oracle中的存儲過程中的關鍵字as沖突的問題吧

2. 在存儲過程中,select某一字段時,后面必須緊跟into,如果select整個記錄,利用游標的話就另當別論了。

 select af.keynode into kn 

from APPFOUNDATION af

where af.appid=aid and af.foundationid=fid;   -- into,正確編譯

select af.keynode 

from APPFOUNDATION af 

where af.appid=aid and af.foundationid=fid;-- 沒有into,編譯報錯,提示:Compilation   Error: PLS-00428: an INTO clause is expected in this SELECT statement

3. 在利用select...into...語法時,必須先確保數(shù)據(jù)庫中有該條記錄,否則會報出"no data found"異常。

可以在該語法之前,先利用select count(*) from 查看數(shù)據(jù)庫中是否存在該記錄,如果存在,再利用select...into...

4. 在存儲過程中,別名不能和字段名稱相同,否則雖然編譯可以通過,但在運行階段會報錯

 select keynode into kn from APPFOUNDATION where appid=aid and foundationid=fid;

-- 正確運行

select af.keynode into kn from APPFOUNDATION af where af.appid=appid and af.foundationid=foundationid;

-- 運行階段報錯,提示
ORA-01422:exact fetch returns more than requested number of rows

5. 在存儲過程中,關于出現(xiàn)null的問題

假設有一個表A,定義如下:

create table A(
id varchar2(50) primary key not null,
vcount number(8) not null,
bid varchar2(50) not null -- 外鍵 
);

如果在存儲過程中,使用如下語句:

select sum(vcount) into fcount from A where bid='xxxxxx';

如果A表中不存在bid="xxxxxx"的記錄,則fcount=null(即使fcount定義時設置了默認值,如:fcount number(8):=0依然無效,fcount還是會變成null),這樣以后使用fcount時就可能有問題,所以在這里最好先判斷一下:

if fcount is null then
    fcount:=0;
end if;

這樣就一切ok了。

6. Hibernate調用Oracle存儲過程

    this.pnumberManager.getHibernateTemplate().execute(

            new HibernateCallback() ...{

               public Object doInHibernate(Session session)

                        throws HibernateException, SQLException ...{

                   CallableStatement cs = session

                           .connection()

                           .prepareCall("{call modifyapppnumber_remain(?)}");

                   cs.setString(1, foundationid);

                   cs.execute();

                   return null;

               }

           });

Java調用Oracle存儲過程總結 

一、 無返回值的存儲過程

測試表:

-- Create table

create table TESTTB

(

  ID   VARCHAR2(30),

  NAME VARCHAR2(30)

)

tablespace BOM

  pctfree 10

  initrans 1

  maxtrans 255

  storage

  (

    initial 64K

    minextents 1

    maxextents unlimited

  );

存儲過程為(當然了,這就先要求要建張表TESTTB,里面兩個字段(I_ID,I_NAME)。

)

CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2, PARA2 IN VARCHAR2) AS

BEGIN

  INSERT INTO BOM.TESTTB(ID, NAME) VALUES (PARA1, PARA2);

END TESTA;

Java里調用時就用下面的代碼:

package com.yiming.procedure.test;

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class TestProcedureDemo1 {

public TestProcedureDemo1() {

}

public static void main(String[] args) {

String driver = "Oracle.jdbc.driver.OracleDriver";

String strUrl = "jdbc:Oracle:thin:@10.20.30.30:1521:vasms";

Statement stmt = null;

ResultSet rs = null;

Connection conn = null;

CallableStatement proc = null;

try {

Class.forName(driver);

conn = DriverManager.getConnection(strUrl, "bom", "bom");

proc = conn.prepareCall("{ call BOM.TESTA(?,?) }");

proc.setString(1, "100");

proc.setString(2, "TestOne");

proc.execute();

} catch (SQLException ex2) {

ex2.printStackTrace();

} catch (Exception ex2) {

ex2.printStackTrace();

} finally {

try {

if (rs != null) {

rs.close();

if (stmt != null) {

stmt.close();

}

if (conn != null) {

conn.close();

}

}

} catch (SQLException ex1) {

}

}

}

}

二、 有返回值的存儲過程(非列表)

例:存儲過程為:

CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2, PARA2 OUT VARCHAR2) AS

BEGIN

  SELECT NAME INTO PARA2 FROM TESTTB WHERE ID = PARA1;

END TESTB;

Java里調用時就用下面的代碼:

package com.yiming.procedure.test;

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.sql.Types;

public class TestProcedureDemo2 {

public static void main(String[] args) {

String driver = "Oracle.jdbc.driver.OracleDriver";

String strUrl = "jdbc:Oracle:thin:@10.20.30.30:1521:vasms";

Statement stmt = null;

ResultSet rs = null;

Connection conn = null;

CallableStatement proc = null;

try {

Class.forName(driver);

conn = DriverManager.getConnection(strUrl, "bom", "bom");

proc = conn.prepareCall("{ call BOM.TESTB(?,?) }");

proc.setString(1, "100");

proc.registerOutParameter(2, Types.VARCHAR);

proc.execute();

String testPrint = proc.getString(2);

System.out.println("=testPrint=is=" + testPrint);

} catch (SQLException ex2) {

ex2.printStackTrace();

} catch (Exception ex2) {

ex2.printStackTrace();

} finally {

try {

if (rs != null) {

rs.close();

if (stmt != null) {

stmt.close();

}

if (conn != null) {

conn.close();

}

}

} catch (SQLException ex1) {

}

}

}

}

注意,這里的proc.getString(2)中的數(shù)值2并非任意的,而是和存儲過程中的out列對應的,如果out是在第一個位置,那就是proc.getString(1),如果是第三個位置,就是proc.getString(3),當然也可以同時有多個返回值,那就是再多加幾個out參數(shù)了。

三、 返回列表

由于Oracle存儲過程沒有返回值,它的所有返回值都是通過out參數(shù)來替代的,列表同樣也不例外,但由于是集合,所以不能用一般的參數(shù),必須要用pagkage.所以要分兩部分,

1. 建一個程序包。如下:

CREATE OR REPLACE PACKAGE TESTPACKAGE AS

  TYPE TEST_CURSOR IS REF CURSOR;

end TESTPACKAGE;

2. 建立存儲過程,存儲過程為:

CREATE OR REPLACE PROCEDURE TESTC(P_CURSOR out TESTPACKAGE.TEST_CURSOR) IS

BEGIN

  OPEN P_CURSOR FOR

    SELECT * FROM BOM.TESTTB;

END TESTC;

可以看到,它是把游標(可以理解為一個指針),作為一個out 參數(shù)來返回值的。

Java里調用時就用下面的代碼:

在這里要注意,在執(zhí)行前一定要先把Oracle的驅動包放到class路徑里,否則會報錯的。

package com.yiming.procedure.test;

import java.sql.CallableStatement;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class TestProcedureDemo3 {

public static void main(String[] args) {

String driver = "Oracle.jdbc.driver.OracleDriver";

String strUrl = "jdbc:Oracle:thin:@10.20.30.30:1521:vasms";

Statement stmt = null;

ResultSet rs = null;

Connection conn = null;

CallableStatement proc = null;

try {

Class.forName(driver);

conn = DriverManager.getConnection(strUrl, "bom", "bom");

proc = conn.prepareCall("{ call bom.testc(?) }");

proc.registerOutParameter(1, Oracle.jdbc.OracleTypes.CURSOR);

proc.execute();

rs = (ResultSet) proc.getObject(1);

while (rs.next()) {

System.out.println("<tr><td>" + rs.getString(1) + "</td><td>"

+ rs.getString(2) + "</td></tr>");

}

} catch (SQLException ex2) {

ex2.printStackTrace();

} catch (Exception ex2) {

ex2.printStackTrace();

} finally {

try {

if (rs != null) {

rs.close();

if (stmt != null) {

stmt.close();

}

if (conn != null) {

conn.close();

}

}

} catch (SQLException ex1) {

}

}

}

}

在存儲過程中做簡單動態(tài)查詢

在存儲過程中做簡單動態(tài)查詢代碼 ,例如: 

CREATE OR REPLACE procedure ZXM_SB_GZ_GET
  (p_table in varchar2,
  p_name in varchar2,
  p_value in varchar2,
  outpara out lntxdba.zxm_pag_cs_power.c_type
  )
  as
  begin
  declare
  wherevalue varchar2(200);
  begin
  wherevalue:=select * from ||p_table|| where ||p_name||=||p_value;
  open outpara for
  wherevalue;
  end;
  end;

一般的PL/SQL程序設計中,在DML和事務控制的語句中可以直接使用SQL,但是DDL語句及系統(tǒng)控制語句卻不能在PL/SQL中直接使用,要想實現(xiàn)在PL/SQL中使用DDL語句及系統(tǒng)控制語句,可以通過使用動態(tài)SQL來實現(xiàn)。

首先我們應該了解什么是動態(tài)SQL,在Oracle數(shù)據(jù)庫開發(fā)PL/SQL塊中我們使用的SQL分為:靜態(tài)SQL語句和動態(tài)SQL語句。所謂靜態(tài)SQL指在PL/SQL塊中使用的SQL語句在編譯時是明確的,執(zhí)行的是確定對象。而動態(tài)SQL是指在PL/SQL塊編譯時SQL語句是不確定的,如根據(jù)用戶輸入的參數(shù)的不同而執(zhí)行不同的操作。編譯程序對動態(tài)語句部分不進行處理,只是在程序運行時動態(tài)地創(chuàng)建語句、對語句進行語法分析并執(zhí)行該語句。

Oracle中動態(tài)SQL可以通過本地動態(tài)SQL來執(zhí)行,也可以通過DBMS_SQL包來執(zhí)行。下面就這兩種情況分別進行說明:

一、 本地動態(tài)SQL

本地動態(tài)SQL是使用EXECUTE IMMEDIATE語句來實現(xiàn)的。

1、 本地動態(tài)SQL執(zhí)行DDL語句:

需求:根據(jù)用戶輸入的表名及字段名等參數(shù)動態(tài)建表。

create or replace procedure proc_test
(
     table_name in varchar2,      --表名
     field1 in varchar2,           --字段名
     datatype1 in varchar2,       --字段類型
     field2 in varchar2,           --字段名
     datatype2 in varchar2        --字段類型
) as 
     str_sql varchar2(500);
begin 
     str_sql:=’create table ’||table_name||’(’||field1||’ ’||datatype1||’,’||field2||’ ’||datatype2||’)’;
    execute immediate str_sql;    --動態(tài)執(zhí)行DDL語句
    exception 
        when others then 
            null;
end ;

以上是編譯通過的存儲過程代碼。下面執(zhí)行存儲過程動態(tài)建表。

SQL> execute proc_test(’dinya_test’,’id’,’number(8) not null’,’name’,’varchar2(100)’);

PL/SQL procedure successfully completed

SQL> desc dinya_test;
Name Type           Nullable Default Comments 
---- ------------- -------- ------- -------- 
ID   NUMBER(8)

NAME VARCHAR2(100) Y

SQL>

到這里,就實現(xiàn)了我們的需求,使用本地動態(tài)SQL根據(jù)用戶輸入的表名及字段名、字段類型等參數(shù)來實現(xiàn)動態(tài)執(zhí)行DDL語句。

2、 本地動態(tài)SQL執(zhí)行DML語句。

需求:將用戶輸入的值插入到上例中建好的dinya_test表中。

create or replace procedure proc_insert
(
    id in number,                                  --輸入序號
    name in varchar2                              --輸入姓名
) as 
     str_sql varchar2(500);
begin 
     str_sql:=’insert into dinya_test values(:1,:2)’;
    execute immediate str_sql using id,name; --動態(tài)執(zhí)行插入操作
    exception 
        when others then 
            null;
end ;


執(zhí)行存儲過程,插入數(shù)據(jù)到測試表中。

SQL> execute proc_insert(1,’dinya’);
PL/SQL procedure successfully completed
SQL> select * from dinya_test;
        ID      NAME
         1       dinya

在上例中,本地動態(tài)SQL執(zhí)行DML語句時使用了using子句,按順序將輸入的值綁定到變量,如果需要輸出參數(shù),可以在執(zhí)行動態(tài)SQL的時候,使用RETURNING INTO 子句,如:

declare
     p_id number:=1;
     v_count number;
begin 
     v_string:=’select count(*) from table_name a where a.id=:id’;
    execute immediate v_string into v_count using p_id;  
end ;

二、 使用DBMS_SQL

使用DBMS_SQL包實現(xiàn)動態(tài)SQL的步驟如下:

A、先將要執(zhí)行的SQL語句或一個語句塊放到一個字符串變量中。

B、使用DBMS_SQL包的parse過程來分析該字符串。

C、使用DBMS_SQL包的bind_variable過程來綁定變量。

D、使用DBMS_SQL包的execute函數(shù)來執(zhí)行語句。

1、使用DBMS_SQL包執(zhí)行DDL語句

需求:使用DBMS_SQL包根據(jù)用戶輸入的表名、字段名及字段類型建表。

create or replace procedure proc_dbms_sql
(
     table_name in varchar2,        --表名
     field_name1 in varchar2,       --字段名
     datatype1 in varchar2,         --字段類型
     field_name2 in varchar2,       --字段名
     datatype2 in varchar2          --字段類型
)as
     v_cursor number;               --定義光標
     v_string varchar2(200);       --定義字符串變量
     v_row number;                   --行數(shù)
begin
     v_cursor:=dbms_sql.open_cursor;      --為處理打開光標
     v_string:=’create table ’||table_name||’(’||field_name1||’ ’||datatype1||’,’||field_name2||’ ’||datatype2||’)’;
     dbms_sql.parse(v_cursor,v_string,dbms_sql.native);     --分析語句
     v_row:=dbms_sql.execute(v_cursor);    --執(zhí)行語句
     dbms_sql.close_cursor(v_cursor);      --關閉光標
    exception
        when others then
             dbms_sql.close_cursor(v_cursor);   --關閉光標
            raise;
end;

以上過程編譯通過后,執(zhí)行過程創(chuàng)建表結構:

SQL> execute proc_dbms_sql(’dinya_test2’,’id’,’number(8) not null’,’name’,’varchar2(100)’);

PL/SQL procedure successfully completed

SQL> desc dinya_test2;
Name Type           Nullable Default Comments 
---- ------------- -------- ------- -------- 
ID   NUMBER(8)                               
NAME VARCHAR2(100) Y                         

SQL>

2、 使用DBMS_SQL包執(zhí)行DML語句

需求:使用DBMS_SQL包根據(jù)用戶輸入的值更新表中相對應的記錄。

查看表中已有記錄:

SQL> select * from dinya_test2;
       ID NAME
         1 Oracle
         2 CSDN
         3 ERP
SQL>

建存儲過程,并編譯通過:

create or replace procedure proc_dbms_sql_update
(
    id number,
    name varchar2
)as
     v_cursor number;             --定義光標
     v_string varchar2(200);    --字符串變量
     v_row number;                --行數(shù)
begin
     v_cursor:=dbms_sql.open_cursor;     --為處理打開光標
     v_string:=’update dinya_test2 a set a.name=:p_name where a.id=:p_id’;
     dbms_sql.parse(v_cursor,v_string,dbms_sql.native);    --分析語句
     dbms_sql.bind_variable(v_cursor,’:p_name’,name);      --綁定變量
     dbms_sql.bind_variable(v_cursor,’:p_id’,id);           --綁定變量
     v_row:=dbms_sql.execute(v_cursor);           --執(zhí)行動態(tài)SQL
     dbms_sql.close_cursor(v_cursor);                         --關閉光標
    exception
        when others then
             dbms_sql.close_cursor(v_cursor);                 --關閉光標
            raise;
end;

執(zhí)行過程,根據(jù)用戶輸入的參數(shù)更新表中的數(shù)據(jù):

SQL> execute proc_dbms_sql_update(2,’csdn_dinya’);

PL/SQL procedure successfully completed

SQL> select * from dinya_test2;
       ID NAME
         1 Oracle
         2 csdn_dinya
         3 ERP
SQL>

執(zhí)行過程后將第二條的name字段的數(shù)據(jù)更新為新值csdn_dinya。這樣就完成了使用dbms_sql包來執(zhí)行DML語句的功能。

使用DBMS_SQL中,如果要執(zhí)行的動態(tài)語句不是查詢語句,使用DBMS_SQL.ExecuteDBMS_SQL.Variable_Value來執(zhí)行,如果要執(zhí)行動態(tài)語句是查詢語句,則要使用DBMS_SQL.define_column定義輸出變量,然后使用DBMS_SQL.Execute, DBMS_SQL.Fetch_Rows, DBMS_SQL.Column_ValueDBMS_SQL.Variable_Value來執(zhí)行查詢并得到結果。

  總結說明:

Oracle開發(fā)過程中,我們可以使用動態(tài)SQL來執(zhí)行DDL語句、DML語句、事務控制語句及系統(tǒng)控制語句。但是需要注意的是,PL/SQL塊中使用動態(tài)SQL執(zhí)行DDL語句的時候與別的不同,在DDL中使用綁定變量是非法的(bind_variable(v_cursor,’:p_name’,name)),分析后不需要執(zhí)行DBMS_SQL.Bind_Variable,直接將輸入的變量加到字符串中即可。另外,DDL是在調用DBMS_SQL.PARSE時執(zhí)行的,所以DBMS_SQL.EXECUTE也可以不用,即在上例中的v_row:=dbms_sql.execute(v_cursor)部分可以不要。

Oracle存儲過程調用Java方法

存儲過程中調用Java程序段

軟件環(huán)境:

1、 操作系統(tǒng):Windows 2000 Server

2、 數(shù) 據(jù) 庫:Oracle 8i R2 (8.1.7) for NT 企業(yè)版

3、 安裝路徑:C:\ORACLE

實現(xiàn)方法:

1、 創(chuàng)建一個文件為Test.java

public class Test {

public static void main(String args[]) {

System.out.println("HELLO THIS iS A Java PROCEDURE");

}

}

2、 javac Test.java

3、 java Test

4、 SQL> conn system/manager

SQL> grant create any directory to scott;

SQL> conn scott/tiger

SQL> create or replace directory test_dir as 'd:\';

目錄已創(chuàng)建。

SQL> create or replace java class using bfile(test_dir,'TEST.CLASS')

2 /

Java 已創(chuàng)建。

SQL> select object_name,object_type,STATUS from user_objects;

SQL> create or replace procedure test_java

as language java

name 'TEST.main(java.lang.String[])';

/

過程已創(chuàng)建。

SQL> set serveroutput on size 5000

SQL> call dbms_java.set_output(5000);

調用完成。

SQL> execute test_java;

HELLO THIS iS A Java PROCEDURE

PL/SQL 過程已成功完成。

SQL> call test_java();

HELLO THIS iS A Java PROCEDURE

調用完成。

Oracle  8I 9I測試通過。

Oracle高效分頁存儲過程實例

create or replace package p_page is
  -- Author  : PHARAOHS
  -- Created : 2006-4-30 14:14:14
  -- Purpose : 分頁過程
  TYPE type_cur IS REF CURSOR;     --定義游標變量用于返回記錄集
  
  PROCEDURE Pagination(
  Pindex in number,                --分頁索引
  Psql in varchar2,                --產(chǎn)生datasetsql語句
  Psize in number,                 --頁面大小
  Pcount out number,               --返回分頁總數(shù)
  v_cur out type_cur               --返回當前頁數(shù)據(jù)記錄
  );

  procedure PageRecordsCount(
  Psqlcount in varchar2,           --產(chǎn)生datasetsql語句
  Prcount   out number             --返回記錄總數(shù)
  );

end p_page;
/
create or replace package body p_page is

PROCEDURE Pagination(
  Pindex in number,
  Psql in varchar2,
  Psize in number, 
  Pcount out number,
  v_cur out type_cur
 )
 AS

  v_sql VARCHAR2(1000);
  v_count number; 
  v_Plow number;
  v_Phei number;
 Begin
  ------------------------------------------------------------取分頁總數(shù)
  v_sql := 'select count(*) from (' || Psql || ')';
  execute immediate v_sql into v_count;
  Pcount := ceil(v_count/Psize);
  ------------------------------------------------------------顯示任意頁內容
  v_Phei := Pindex * Psize + Psize;
  v_Plow := v_Phei - Psize + 1;
  --Psql := 'select rownum rn,t.* from zzda t' ;            --要求必須包含rownum字段
  v_sql := 'select * from (' || Psql || ') where rn between ' || v_Plow || ' and ' || v_Phei ;

  open v_cur for v_sql;
 
 End Pagination;
 
 --**************************************************************************************
 
 procedure PageRecordsCount(
  Psqlcount in varchar2,
  Prcount   out number
  )
  as
 
   v_sql varchar2(1000);
   v_prcount number;
  
  begin
 
   v_sql := 'select count(*) from (' || Psqlcount || ')';
   execute immediate v_sql into v_prcount;
   Prcount := v_prcount;                  --返回記錄總數(shù)                                                     
  
  end PageRecordsCount;
 
 --**************************************************************************************
end p_page;
/

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI