1. 程式人生 > >Oracle 函式和儲存過程的區別和聯絡 總結版

Oracle 函式和儲存過程的區別和聯絡 總結版

 

oracle儲存過程與函式的區別

2017年08月15日 22:49:38 冷月葬花魂iiii 閱讀數:7800更多

個人分類: oracle

定義:

儲存過程(Stored Procedure )是一組為了完成特定功能的SQL 語句集,經編譯後儲存在資料庫中。使用者通過指定儲存過程的名字並給出引數(如果該儲存過程

帶有引數)來執行它。

儲存過程是資料庫中的一個重要物件,任何一個設計良好的資料庫應用程式都應該用到儲存過程。

儲存過程是由流控制和SQL 語句書寫的過程,這個過程經編譯和優化後儲存在資料庫伺服器中,應用程式使用時只要呼叫即可。

Oracle 中,若干個有聯絡的過程可以組合在一起構成程式包。

 

優 點:

1. 儲存過程只在創造時進行編譯,以後每次執行儲存過程都不需再重新編譯,而一般SQL語句每執行一次就編譯一次,所以使用儲存過程可提高資料庫執行速度。

2.當對資料庫進行復雜操作時(如對多個表進行Update、Insert、Query、Delete時),可將此複雜操作用儲存過程封裝起來與資料庫提供的事務處理結合一起使用。

3.儲存過程可以重複使用,可減少資料庫開發人員的工作量。

4.安全性高,可設定只有某使用者才具有對指定儲存過程的使用權。

 

儲存過程與函式的對比

 

儲存過程的優缺點

優點:減少網路互動的成本。
缺點:
a、不可移植性,每種資料庫的內部程式設計語法都不太相同,當你的系統需要相容多種資料庫時,最好不要用儲存過程。
b、學習成本高,DBA一般都擅長寫儲存過程,但並不是每個程式設計師都能寫好儲存過程,除非你的團隊有較多的開發人員熟悉寫儲存過程,否則後期系統維護會產生問題。
c、業務邏輯多處存在,採用儲存過程後也就意味著你的系統有一些業務邏輯不是在應用程式裡處理,這種架構會增加一些系統維護和除錯成本。
d、儲存過程和常用應用程式語言不一樣,它支援的函式及語法有可能不能滿足需求,有些邏輯就只能通過應用程式處理。
e、如果儲存過程中有複雜運算的話,會增加一些資料庫服務端的處理成本,對於集中式資料庫可能會導致系統可擴充套件性問題。
f、為了提高效能,資料庫會把儲存過程程式碼編譯成中間執行程式碼(類似於

Java的class檔案),所以更像靜態語言。當儲存過程引用的對像(表、檢視等等)結構改變後,
儲存過程需要重新編譯才能生效,在24*7高併發應用場景,一般都是線上變更結構的,所以在變更的瞬間要同時編譯儲存過程,這可能會導致資料庫瞬間壓力上升引起故障

 

 

(oracle資料庫就存在這樣的問題)。

 

本質上沒區別。只是函式有如:只能返回一個變數的限制。而儲存過程可以返回多個。而函式是可以嵌入在sql中使用的,可以在select中呼叫,而儲存過程不行。執行的本質都一樣。 
     函式限制比較多,比如不能用臨時表,只能用表變數.還有一些函式都不可用等等.而儲存過程的限制相對就比較少 
      1.    一般來說,儲存過程實現的功能要複雜一點,而函式的實現的功能針對性比較強。 
      2.    對於儲存過程來說可以返回引數,而函式只能返回值或者表物件。 
      3.    儲存過程一般是作為一個獨立的部分來執行(EXEC執行),而函式可以作為查詢語句的一個部分來呼叫(SELECT呼叫),由於函式可以返回一個表物件,因此它可以在查詢語句中位於FROM關鍵字的後面。 
      4.    當儲存過程和函式被執行的時候,SQL Manager會到procedure cache中去取相應的查詢語句,如果在procedure cache裡沒有相應的查詢語句,SQL Manager就會對儲存過程和函式進行編譯。 
      Procedure cache中儲存的是執行計劃 (execution plan) ,當編譯好之後就執行procedure cache中的execution plan,之後SQL SERVER會根據每個execution plan的實際情況來考慮是否要在cache中儲存這個plan,評判的標準一個是這個execution plan可能被使用的頻率;其次是生成這個plan的代價,也就是編譯的耗時。儲存在cache中的plan在下次執行時就不用再編譯了。

https://blog.csdn.net/u012102536/article/details/77203030

 

 

 

竹瀝半夏

 

隨筆- 12  文章- 0  評論- 8 

oracle中函式和儲存過程的區別和聯絡

oracle中函式和儲存過程的區別和聯絡

  在oracle中,函式和儲存過程是經常使用到的,他們的語法中有很多相似的地方,但也有自己的特點。剛學完函式和儲存過程,下面來和大家分享一下自己總結的關於函式和儲存過程的區別。

一、儲存過程

1.定義

  儲存過程是儲存在資料庫中提供所有使用者程式呼叫的子程式,定義儲存過程的關鍵字為procedure。

2.建立儲存過程

  create [or replace] procedure 儲存過程名

  [(引數1 型別,引數2 out 型別……)]                                       

  as

    變數名  型別;

  begin

    程式程式碼體

  end;

  示例一:無參無返

複製程式碼

create or replace procedure p1
--or replace代表建立該儲存過程時,若儲存名存在,則替換原儲存過程,重新建立
--無引數列表時,不需要寫()
as
begin
  dbms_output.put_line('hello world');
end;

--執行儲存過程方式1
set serveroutput on;
begin
  p1();
end;
--執行儲存過程方式2
set serveroutput on;
execute p1();

複製程式碼

  示例二:有參有返

複製程式碼

create or replace procedure p2
(name in varchar2,age int,msg out varchar2)
--引數列表中,宣告變數型別時切記不能寫大小,只寫型別名即可,例如引數列表中的name變數的宣告
--引數列表中,輸入引數用in表示,輸出引數用out表示,不寫時預設為輸入引數。
------------輸入引數不能攜帶值出去,輸出引數不能攜帶值進來,當既想攜帶值進來,又想攜帶值出去,可以用in out
as
begin
  msg:='姓名'||name||',年齡'||age;
  --賦值時除了可以使用:=,還可以用into來實現
  --上面子句等價於select '姓名'||name||',年齡'||age into msg from dual;
end;
--執行儲存過程
set serveroutput on;
declare
  msg varchar2(100);
begin
  p2('張三',23,msg);
  dbms_output.put_line(msg);
end;

複製程式碼

 

  示例三:引數列表中有in out引數

複製程式碼

create or replace procedure p3
(msg in out varchar2)
--當既想攜帶值進來,又想攜帶值出去,可以用in out
as
begin
  dbms_output.put_line(msg); --輸出的為攜帶進來的值
  msg:='我是從儲存過程中攜帶出來的值';
end;


--執行儲存過程
set serveroutput on;
declare
  msg varchar2(100):='我是從攜帶進去的值';
begin
  p3(msg);
  dbms_output.put_line(msg);
end;

複製程式碼

   示例四:儲存過程中定義引數

複製程式碼

create or replace procedure p4
as
  --儲存過程中定義的引數列表
  name varchar(50);
begin
  name := 'hello world';
  dbms_output.put_line(name);
end;
---執行儲存過程
set serveroutput on;
execute p4();

複製程式碼

 

 總結:1.建立儲存過程的關鍵字為procedure。

      2.傳參列表中的引數可以用in,out,in out修飾,引數型別一定不能寫大小。列表中可以有多個輸入輸出引數。

      3.儲存過程中定義的引數列表不需要用declare宣告,宣告引數型別時需要寫大小的一定要帶上大小。

    4.as可以用is替換。

      5.呼叫帶輸出引數的過程必須要宣告變數來接收輸出引數值。

      6.執行儲存過程有兩種方式,一種是使用execute,另一種是用begin和end包住。

      儲存過程雖然有很多優點,但是它卻不能使用return返回值。當需要使用return返回值時,我們可以使用函式。

 

二、儲存函式

1.函式與儲存過程的結構類似,但是函式必須有一個return子句,用於返回函式值。

複製程式碼

create or replace function f1
return varchar--必須有返回值,且宣告返回值型別時不需要加大小
as
  msg varchar(50);
begin
   msg := 'hello world';
   return msg;
end;

--執行函式方式1
select f1() from dual;
--執行函式方式2
set serveroutput on;
begin 
  dbms_output.put_line(f1());
end;

複製程式碼

 

 

 三、儲存過程與儲存函式的區別和聯絡

  相同點:1.建立語法結構相似,都可以攜帶多個傳入引數和傳出引數。

          2.都是一次編譯,多次執行。

  不同點:1.儲存過程定義關鍵字用procedure,函式定義用function。

      2.儲存過程中不能用return返回值,但函式中可以,而且函式中必須有return子句。

      3.執行方式略有不同,儲存過程的執行方式有兩種(1.使用execute2.使用begin和end),函式除了儲存過程的兩種方式外,還可以當做表示式使用,例如放在select中(select f1() form dual;)。

總結:如果只有一個返回值,用儲存函式,否則,一般用儲存過程。

 

分類: oracle基礎

標籤: oracle函式儲存過程函式和儲存過程的區別和聯絡functionprocedurereturn

好文要頂 關注我 收藏該文  

竹瀝半夏
關注 - 6
粉絲 - 11

+加關注

6

0

« 上一篇:oracle系統函式(日期函式)
» 下一篇:oracle使用者和許可權

http://www.cnblogs.com/zlbx/p/4818007.html

 

 

 

 

woonu

業精於勤,荒於嬉;行成於思,毀於隨。——韓愈

隨筆-32  文章-0  評論-2 

儲存過程,儲存函式(Oracle)

儲存過程和儲存函式

指儲存在資料庫中供所有使用者程式呼叫的子程式叫儲存過程、儲存函式。

儲存過程和儲存函式的區別?

儲存函式:可以通過return 語句返回函式值。

儲存過程:不能

除此之外我們可以認為他們是完全一樣的。

 

儲存過程

1、建立儲存過程

用create procedure命令簡歷儲存過程。

語法:

create [or replace] procedure 過程名(引數列表)

as

    PLSQL子程式體;

 

列印hello word

複製程式碼

--列印hello world
create or replace procedure sayhelloworld
as 
  --說明部分
begin 
  dbms_output.put_line('hello world');
end;
/

複製程式碼

編譯後:

2、呼叫儲存過程方法:

1、exec 過程名

2、begin

            過程名;

            過程名;

      end;

       /

 

測試呼叫儲存過程

複製程式碼

--連線資料庫
C:\WINDOWS\system32>sqlplus scott/[email protected]:1521/orcl
SQL>--呼叫方式一
SQL> set serveroutput on
SQL> exec sayhelloworld;
hello world

PL/SQL 過程已成功完成。

SQL> --呼叫方式二:
SQL> begin
  2      sayhelloworld();
  3      sayhelloworld();
  4  end;
  5  /
hello world
hello world

PL/SQL 過程已成功完成。

複製程式碼

帶引數的儲存過程:

複製程式碼

--給指定員工薪水漲100,並且列印漲前和漲後的薪水
create or replace procedure raiseSalary(eno in number) --in為輸入引數
as 
  --說明部分
  psal emp.sal%type;

begin
  --得到漲前的薪水
  select sal into psal from emp where empno=eno;

  update emp set sal=sal+100 where empno=eno;

  --要不要commit?
  --為保證在同一事務中,commit由誰呼叫誰提交
  dbms_output.put_line('漲前:'||psal||'  漲後:'||(psal+100));
end;
/

複製程式碼

測試:

儲存函式

函式(function)為一命名的儲存程式,可帶引數,並返回一計算值。函式和過程的結構類似,但必須有一個return子句,用於返回函式值。函式說明要指定函式名、結果值的型別,以及引數型別等。

儲存函式語法:

create[or replace] functiion 函式名(引數列表) 

return函式值型別

as

    PLSQL子程式體;

 

查詢員工年收入

複製程式碼

--查詢某個員工的年收入
create or replace function queryempincome(eno in number)
return number
as
  --月薪和獎金
  psal   emp.sal%type;
  pcomm  emp.comm%type;
begin
  select sal,comm into psal,pcomm from emp where empno=eno;
  --返回年收入
  return psal*12+nvl(pcomm,0);
end;
/

複製程式碼

測試:

過程和函式中的in 和out

一般來講,過程和函式的區別在於函式可以有一個返回值;而過程沒有返回值。

但過程和函式都可以通過out指定一個或多個輸出引數,我們可以利用out引數,在過程和函式中實現返回多個值。

什麼時候用儲存過程/儲存函式?

原則(不是必須的):

    如果只有一個返回值,用儲存函式;否則,就用儲存過程。

 

儲存過程

複製程式碼

create or replace procedure queryEmpInfo(eno in number,
                                         pname out varchar2,
                                         psal  out number,
                                         pjob  out varchar2)
as 
begin
  select ename,sal,empjob into pname,psal,pjob from emp where empno=eno;
end;

複製程式碼

測試

使用java程式呼叫儲存過程

複製程式碼

/*
     * 儲存過程
     * create or replace procedure queryEmpInfo(eno in number,
     *                                     pename out varchar2,
     *                                     psal out number,
     *                                     pjob out varchar2)
     */
    @Test
    public void testProcedure() {
       // {call <procedure-name>[(<arg1>,<arg2>, ...)]}
       String sql = "{call queryEmpInfo(?,?,?,?)}";
       CallableStatement call = null;
       Connection connection = JDBCUtils.getConnection();
       try {
           call = connection.prepareCall(sql);
          
           //對於in引數,賦值
           call.setInt(1, 7839);
          
           //對於out引數,宣告
           call.registerOutParameter(2, OracleTypes.VARCHAR);
           call.registerOutParameter(3, OracleTypes.NUMBER);
           call.registerOutParameter(4, OracleTypes.VARCHAR);
          
           //執行
           call.execute();
          
           //取出結果
           String name = call.getString(2);
           double sal = call.getDouble(3);
           String job = call.getString(4);
           System.out.println(name + "\t" + sal + "\t" + job);
          
       } catch (SQLException e) {
           e.printStackTrace();
       }finally{
           JDBCUtils.release(connection, call, null);
       }
    }

複製程式碼

使用java程式呼叫儲存函式

複製程式碼

/*
     * 儲存函式
     * create or replace function queryEmpIncome(eno in number) 
       return number
     */
    @Test
    public void testFunction() {
       // {?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
       String sql = "{?=call queryEmpIncome(?)}";
       Connection conn = null;
       CallableStatement call = null;
       try {
           conn = JDBCUtils.getConnection();
           call = conn.prepareCall(sql);
 
           //對於out引數,賦值
           call.registerOutParameter(1, OracleTypes.NUMBER);
          
           //對於in引數,賦值
           call.setInt(2, 7839);
          
           //執行
           call.execute();
          
           //取出資料
           double income = call.getDouble(1);
           System.out.println(income);
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           JDBCUtils.release(conn, call, null);
       }
    }

複製程式碼

在out引數中使用游標

問題:查詢某個部門中所有員工的所有資訊

1、申明包結構

複製程式碼

CREATE OR REPLACE 
PACKAGE MYPACKAGE AS 

  type empcursor is ref cursor;
  --建立儲存過程,輸出引數為自定義型別
  procedure queryEmpList(dno in number,empList out empcursor);

END MYPACKAGE;

複製程式碼

2、建立包體(實現)

複製程式碼

CREATE OR REPLACE
PACKAGE BODY MYPACKAGE AS

  procedure queryEmpList(dno in number,empList out empcursor) AS
  BEGIN
    --實現
    open empList for select * from emp where deptno=dno;

  END queryEmpList;

END MYPACKAGE;

複製程式碼

使用java呼叫帶包的儲存過程

複製程式碼

public void testCursor() {
       // {call <procedure-name>[(<arg1>,<arg2>, ...)]}
      
       String sql = "{call MYPACKAGE.queryEmpList(?,?)}";
       Connection conn = null;
       CallableStatement call = null;
       ResultSet rs = null;
       try {
           conn = JDBCUtils.getConnection();
           call = conn.prepareCall(sql);
 
           //對於in引數,賦值ֵ
           call.setInt(1, 20);
 
           //對於out引數,賦值
           call.registerOutParameter(2, OracleTypes.CURSOR);
 
           //執行
           call.execute();
 
           // 取出結果
           rs = ((OracleCallableStatement)call).getCursor(2);
           while(rs.next()){
              String name = rs.getString("ename");
              double sal = rs.getDouble("sal");
              System.out.println(name+"\t"+sal);
           }
       } catch (Exception e) {
           e.printStackTrace();
       } finally {
           JDBCUtils.release(conn, call, rs);
       }
    }

複製程式碼

此案例游標沒有關閉,原因:當resultSet關閉的時候 游標就close了

分類: 資料庫

好文要頂 關注我 收藏該文  

woonu
關注 - 12
粉絲 - 21

+加關注

1

0

« 上一篇:【深入spring】IoC容器的實現
» 下一篇:PLSQL程式設計(Oracle)

https://www.cnblogs.com/dooor/p/5599351.html

 

 

 

 

Oracle中函式和儲存過程的區別總結版

96 是藍先生 關注

2016.07.21 14:02* 字數 865 閱讀 2306評論 1喜歡 10

昨天下午和今天上午找了也看了很多資料,現在基本上已經把二者的區別理清楚,以後不要再弄混淆,也算是一種小小的進步吧,而不去想以後會怎樣。


一、主要區別

**
**
1、二者最大的區別是:

  • 1).函式(function)總是向呼叫者返回資料,並且一般只返回一個值;
  • 2).儲存過程(procedure)不直接返回資料,但可以改變輸出引數的值,這可以近似看作能返回值,且儲存過程輸出引數的值個數沒有限制。

從一般應用上來看,如果不需要返回值或者需要多個返回值,使用儲存過程,如果只用一個返回值,就使用函式。

2、function定義中只能有DDL(如select等)語句;procedure中主要是DML語句(對資料庫進行復雜操作時,如對多個表進行Update、Insert、Query、Delete時)。

如果想要使用select的結果集,則要使用遊標

**
**
以下需要注意的地方是:

  • 1).定義函式或者儲存過程時,IN/OUT表示呼叫函式時,傳進來或傳出去的引數。如果沒有說明in/out,則預設為in;
  • 2).定義的函式必須要有return子句,其後緊跟著返回值得型別;
  • 3).實際呼叫函式或儲存過程時,在declare中宣告的變數至少應該對應建立的函式或儲存過程中的OUT引數和return引數合起來的個數;
  • 4).可以建立不帶引數(即沒有返回的引數)、沒有變數的儲存過程。

**
**

  • 5)執行方式略有不同,儲存過程的執行方式有兩種(1.使用execute2.使用begin和end),函式除了儲存過程的兩種方式外,還可以當做表示式使用,例如放在select中(select f1() form dual;)。

3、儲存過程的命名最好以proc_打頭,函式則是func_打頭,變數則應該用v_打頭。

Paste_Image.png

二、實際舉例

**
**
1、函式

(1)建立函式
create or replace function get_salary(
    dept_no number,
    emp_count **out** number)
    return number IS
    v_sum number;
begin
    ...
exception
    ...
end get_salary

(2)呼叫函式
declare 
    v_num number;
    v_sum number;
begin
    ...(這裡應該出現函式名錶示呼叫)
end

2、儲存過程

(1)建立儲存過程
create or replace procedure pro_demo(
    dept_no number default 10,
    sal_sum out number,
    emp_count out number)
IS
begin
    ...
exception
    ...
end proc_demo;

(2)呼叫儲存過程
呼叫語法:

1)、exec <過程名>;

2)、execute <過程名>;

3)、在PL/SQL語句塊中直接呼叫。
例如:    
declare
    v_num number;
    v_sum number(8,2);
begin
    procedure pro_demo(dept_no=>1,sal_num=>900,emp_count=>10)(這裡出現儲存過程名錶示呼叫,傳遞引數值用=>)
end;

3、本地儲存過程

在PL/SQL中還可以在declare塊中建立本地儲存過程,而不使用關鍵字create,其目的是:不用將儲存過程儲存在資料庫中,避免更改資料庫時帶來的麻煩,其主要的使用場景是,臨時使用某個儲存過程,而不是在以後要重複多次使用。

例子:
declare
    v_num number;
    v_sum number(8,2);
procedure proc_demo(
    dept_no number default 10,
    sal_sum out number,
    emp_count out number)
IS
begin
    ...(這裡不用出現儲存過程名)
exception
    ...
end proc_demo;

**
**

這裡再次複習一下DDL(data defined language),DML(data manipulation language ),DCL(data control language)的區別:

  • 1).DDL的操作物件(表)
    Create語句:可以建立資料庫和資料庫的一些物件。
    Drop語句:可以刪除資料表、索引、觸發程式、條件約束以及資料表的許可權等。
    Alter語句:修改資料表定義及屬性。

  • 2).DML操作的物件是記錄(即資料)
    最常見的是增(insert)、刪(delete)、改(update)、查(select)

  • 3).DCL操作的物件是資料庫使用者的許可權
    Grant語句:允許物件的建立者給某使用者或某組或所有使用者(PUBLIC)某些特定的許可權。
    Revoke語句:可以廢除某使用者或某組或所有使用者訪問許可權

如果寫的對你有一點點幫助,可以手動關注一下下,多謝(*¯︶¯*)

讚賞支援

 資料庫學習

© 著作權歸作者所有

舉報文章

96關注是藍先生

寫了 106083 字,被 623 人關注,獲得了 527 個喜歡

願我長命百歲,yu你終老

喜歡

 

10

   更多分享

Web note ad 1

登入 後發表評論

1條評論 只看作者

按時間倒序按時間正序

 親親子佩_悠悠我思

2樓 · 2017.03.07 19:38

收藏了,謝謝分享

  回覆

https://www.jianshu.com/p/5a90ccd9b643

 

 

 

 

 

oracle之儲存過程(procedure)與函式(function)

2017年09月21日 13:16:08 沒腿的鳥 閱讀數:382更多

個人分類: Oracle

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/qq30211478/article/details/78050830

(一)儲存過程(procedure)

          對於PLSql程式的使用,如果每次使用都要進行編寫,會非常的麻煩,這時可以採用過程和函式來命名PLSQL程式,被編譯後儲存到資料庫中,以備後續使用。

    過程和函式統稱為PL/SQL子程式,他們是被命名的PL/SQL塊,均儲存在資料庫中,並通過輸入、輸出引數或輸入/輸出引數與其呼叫者交換資訊。過程和函式的唯一區別是函式總向呼叫者返回資料,而過程則不返回資料。

在編譯儲存過程報錯時,可以使用show  error命令檢視具體錯誤原因。

(二)儲存過程格式

 

create or replace procedure 儲存過程名(
para1 varchar2,
para2 out varchar2,
para3 in out varchar2
) as|is      //is與as一樣的作用
v_name varchar2(20);
begin
 v_name :='zhangsf';
 para3 := v_name;
dbms_output.put_line('para3:'||para3);
end;

複製程式碼

 

上面就是一個最簡單的儲存過程。一個儲存過程大體分為這麼幾個部分: 
1、建立語句:create or replace procedure 儲存過程名 
如果沒有or replace語句,則僅僅是新建一個儲存過程。如果系統存在該儲存過程,則會報錯。Create or replace procedure 如果系統中沒有此儲存過程就新建一個,如果系統中有此儲存過程則把原來刪除掉,重新建立一個儲存過程。
2、儲存過程名定義:包括儲存過程名和引數列表。

引數名和引數型別。引數名不能重複, 引數傳遞方式:IN, OUT, IN OUT 
IN 表示輸入引數,按值傳遞方式。 
OUT 表示輸出引數,可以理解為按引用傳遞方式。可以作為儲存過程的輸出結果,供外部呼叫者使用。 
IN OUT 即可作輸入引數,也可作輸出引數。 
引數的資料型別只需要指明型別名即可,不需要指定寬度。 
引數的寬度由外部呼叫者決定。 
過程可以有引數,也可以沒有引數 
3、變數宣告塊:緊跟著的as (is )關鍵字,可以理解為pl/sql的declare關鍵字,用於宣告變數。 
變數宣告塊用於宣告該儲存過程需要用到的變數,它的作用域為該儲存過程。另外這裡宣告的變數必須指定寬度。遵循PL/SQL的變數宣告規範。 
4、過程語句塊:從begin 關鍵字開始為過程的語句塊。儲存過程的具體邏輯在這裡來實現。 
5、異常處理塊:關鍵字為exception ,為處理語句產生的異常。該部分為可選 
6、結束塊:由end關鍵字結果。 

7、 一般,只有在確認function_name函式是新函式或是要更新的函式時,才使用OR REPALCE關鍵字,否則容易刪除有用的函式。

8、  IN,OUT,IN OUT是形參的模式。若省略,則為IN模式。IN模式的形參只能將實參傳遞給形參,進入函式內部,但只能讀不能寫,函式返回時實參的值不變。OUT模式的形參會忽略呼叫時的實參值(或說該形參的初始值總是NULL),但在函式內部可以被讀或寫,函式返回時形參的值會賦予給實參。IN OUT具有前兩種模式的特性,即呼叫時,實參的值總是傳遞給形參,結束時,形參的值傳遞給實參。呼叫時,對於IN模式的實參可以是常量或變數,但對於OUT和IN OUT模式的實參必須是變數。

(三)執行儲存過程、函式

exec   儲存過程名(函式);

或者

begin 

  儲存過程名;

end;

(四)函式(與儲存過程類似)

CREATE [OR REPLACE] FUNCTION function_name
 (arg1 [ { IN | OUT | IN OUT }] type1 [DEFAULT value1],
 [arg2 [ { IN | OUT | IN OUT }] type2 [DEFAULT value1]],
 ......
 [argn [ { IN | OUT | IN OUT }] typen [DEFAULT valuen]])
 [ AUTHID DEFINER | CURRENT_USER ]
RETURN return_type 
 IS | AS
    <型別.變數的宣告部分> 
BEGIN
    執行部分
    RETURN expression
EXCEPTION
    異常處理部分
END;

 

(五)例項

create or replace procedure p
is
  cursor c
  is
    select * from emp2 for update;
begin
   for v_temp in c loop
      if (v_temp.deptno = 10) then
         update emp2 set sal = sal + 10 where current of c;
      elsif (v_temp.deptno = 20) then
         update emp2 set sal = sal + 20 where current of c;
      else
         update emp2 set sal = sal + 50 where current of c;
      end if;
    end loop;
    commit;
end;
--執行 
exec p;

begin;
 p;
end;
--帶引數的儲存過程
create or replace procedure p
     (v_a in number, v_b number, v_ret out number, v_temp in out number)
is
begin
   if (v_a > v_b) then
      v_ret := v_a;
   else
      v_ret := v_b;
   end if;
   v_temp := v_temp + 1;
end;


--實驗
declare
 v_a number := 3;
 v_b number := 4;
 v_ret number;    //用來儲存函式的輸出結果,供呼叫者使用
 v_temp number := 5;
begin
 p(v_a, v_b, v_ret, v_temp);  //直接呼叫函式並出入引數
 dbms_output.put_line(v_ret);    
 dbms_output.put_line(v_temp);
end;
-------------------
--函式
create or replace function sal_tax
  (v_sal number)
  return number
is
begin
   if (v_sal < 2000) then
      return 0.10;
   elsif (v_sal < 2750) then
      return 0.15;
   else
      return 0.20;
   end if;
end;

 

--查詢oracle中的儲存過程:

方法一:
select * from user_procedures;
方法二:
select object_name,object_type,procedure_name from dba_procedures where object_type='PROCEDURE' and owner='SCOTT';

 

 

select  name from user_source where  type='PROCEDURE';

或者:

select object_name from user_procedures;

或者:

select object_name from user_objects where object_type='PROCEDURE' ;

②找到你所要查詢的儲存過程名字後,執行下面操作,可以看到存錯過程內容:

select  text from user_source where name ='xxxx';--(xxxx代表所要查詢的儲存過程名字)

------------------------------------------------

如果是函式,類似的方法,只需要把PROCEDURE,換成FUNCTION即可

刪除儲存過程和函式

drop  procedure   儲存過程名;

drop  function   函式名;

https://blog.csdn.net/qq30211478/article/details/78050830