1. 程式人生 > >Oracle 動態遊標 PL/SQL 動態SQL語句 open for [using] 語句

Oracle 動態遊標 PL/SQL 動態SQL語句 open for [using] 語句

PL/SQL:open for [using] 語句

2017年07月19日 09:52:55 學孩兒無牙哭做粥 閱讀數:681 標籤: oracleSQLPLSQL 更多

個人分類: ORACLESQL/PLSQL

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

 


※ OPEN FOR [USING] 語句 ※


目的:

        和ref cursor配合使用, 可以將遊標變數分配給不同的SQL (而不是在declare中把遊標給定死), 增加處理遊標的靈活性

語法:

declare

    type type_cursor  is ref cursor [return 記錄型別];  --使用 ref cursor 才能把遊標分配給不同的SQL,return不能用在動態SQL中

    v_cursor type_cursor ;

begin

    OPEN v_cursor FOR select first_name, last_name from student;

 

    OPEN v_cursor FOR select first_name,last_name  from student where zip = :1 '

    USING 繫結變數1;

 

 

open 靜態SQL cursor cursor c1 is <靜態SQL文字>
open c1; fetch ... into ... ; close c1;
open for     靜態SQL     ref cursor type t_1 is ref cursor;
c2  t_1 ;
open c2 for <靜態SQL語句>;
open for using 動態SQL type t_1 is ref cursor;
c2  t_1 ;
open c2 for <動態SQL語句> using ... ;

 

 

例子1:

declare

  type student_cur_type is ref CURSOR RETURN test_stu%ROWTYPE;  --宣告ref cursor型別, return型別固定

    v_first_name test_stu.first_name%TYPE;

    v_last_name test_stu.last_name%TYPE;

  cur_stud student_cur_type;

begin

  open cur_stud for select first_name,last_name from student ;  --帶return的ref cursor只能用在靜態sql中

 loop

    fetch cur_stud into v_first_name, v_last_name;

    exit when cur_stud%NOTFOUND;

    dbms_output.put_line(v_first_name || ' ' || v_last_name);

  end loop;

  close cur_stud; 

end;

 

例子2:

declare

  v_zip        varchar2(5) := '&sv_zip';

  v_first_name varchar2(25);

  v_last_name  varchar2(25);

 

  type student_cur_type is ref cursor;  --宣告ref cursor型別

  student_cur student_cur_type;  --student_cur是遊標變數 / student_cur_type 是引用遊標型別

begin

  --2開啟遊標變數,讓它指向一個動態select查詢的結果集 ; 就是使用open for語句代替一般的open語句代開遊標

  open student_cur for 'select first_name,last_name ' from student where zip = :1'

    using v_zip;

  loop

    fetch student_cur into v_first_name, v_last_name;

    exit when student_cur%NOTFOUND;

    dbms_output.put_line(v_first_name || ' ' || v_last_name);

  end loop;

  close student_cur;

end;

 

https://blog.csdn.net/crzzyracing/article/details/75336196


 

 

 

 

動態SQL中使用Open for語句

2017年09月06日 19:35:55 keven2840 閱讀數:3199 標籤: 動態sqlopen for多行動態查詢 更多

個人分類: Oracle之SQL和PLSQL

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

Open for本是為了支援遊標變數,現在用它實現多行動態查詢。OPEN FOR的語法如下:

OPEN{cursor_variable | :host_cursor_viable}FOR SQL_string

                [USING bind_argument [, bind_argument]…];

解釋:

Cursor_variable是一種弱型別的遊標變數。

:host_cursor_variable是在PL/SQL宿主環境下宣告的遊標變數,如Oracle呼叫介面程式。

SQL_string包含動態執行的SELECT語句。

USING子句與EXECUTE IMMEDIATE語句遵循相同的規則。

使用OPEN FOR語句開啟動態查詢的例子:

PROCEDURE show_parts_inventory(

 parts_table IN VARCHAR2, where_in IN VARCHAR2)

IS

 TYPE query_curtype IS REF CURSOR;

 dyncur query_curtype; 

BEGIN

 OPEN dyncur FOR

      'SELECT * FROM' || parts_table || 'WHERE' || where_in;

                。。。

執行OPEN FOR語句時,PL/SQL執行引擎操作如下:

1、  將遊標變數與在查詢字串找到的查詢相關聯。

2、  對繫結引數求值,並用這些值替換查詢字串內的佔位符。

3、  執行查詢。

4、  識別結果集。

5、  將遊標放在結果集第一行。

6、  把由%ROWCOUNT返回的行計數值歸零。

注意,查詢中任何繫結引數(由USING子句提供),僅當遊標變數開啟時才能求值。這意味著如果我們想對相同的動態查詢使用不同的繫結引數值,

就必須使用該引數再執行一次OPEN FOR語句。

執行多行查詢需遵循以下步驟:

1、  宣告一個REFCURSOR型別(或使用Oracle定義的SYS_REFCURSOR弱CURSOR型別)。

2、  基於這個REF CURSOR型別宣告一個遊標變數。

3、  用這個遊標變數開啟查詢字串。

4、  使用FETCH語句提供查詢確認的一行或多行結果集。

5、  必要時檢查遊標屬性(%FOUND、%NOTFOUND、%ROWCOUNT、%ISOPEN)。

6、  使用標準CLOSE語句關閉遊標變數。

 

/*顯示任何一個表中由WHERE子句所選出的行的指定列的內容(對數字、日期和字串列有效)*/

/*引數說明:tab:表名、col:列名、whr:條件*/

PROCEDURE showcol(tab IN VARCHAR2,

                  col IN Varchar2,

                  whr IN VARCHAR2:=NULL)

IS

         cv SYS_REFCURSOR;

         val VARCHAR2(32767);

BEGIN

 OPEN cv FOR

--注意字串之間的空格

      'SELECT ' || col ||

      ' FROM ' || tab ||

      ' WHERE ' || NVL(whr, '1 = 1');

 LOOP

   --取cv的值給val,如果找不到就退出,和顯示遊標相同

   FETCH cv INTO val;

   EXIT WHEN cv%NOTFOUND;

   --如果取到第一行,顯示頭部的資訊

    IFcv%ROWCOUNT = 1

     THEN

       Dbms_Output.put_line(RPAD('_',60,'_'));

       Dbms_Output.put_line(

                   'Contents of ' || UPPER(tab)|| '.' || UPPER(col));

       Dbms_Output.put_line(RPAD('_',60,'_'));

     END IF;

     Dbms_Output.put_line(val);

  END LOOP;

   --記得關閉遊標

  CLOSE cv;

END;

 

/*升級版showcol程式,顯示帶有一個時間列,並且時間列在一定範圍數值內的所有列的資訊*/

PROCEDURE showcol(tab VARCHAR2,

                      col VARCHAR2,

                      dtcol VARCHAR2,

                      dt1 DATE,

                      dt2 DATE := NULL)

IS

   cvSYS_REFCURSOR;

  val VARCHAR2(32767);

BEGIN

 OPEN cv FOR

  --注意空格

      'SELECT ' || col ||

      ' FROM ' || tab ||

      ' WHERE ' || dtcol ||

      ' BETWEEN TRUNC (:startdt) AND TRUNC (:enddt)'

    USING dt1, NVL (dt2, dt1+1);

 LOOP

   --取cv的值給val,如果找不到就退出

   FETCH cv INTO val;

   EXIT WHEN cv%NOTFOUND;

   --如果取到第一行,顯示資訊

   IF cv%ROWCOUNT = 1

     THEN

       Dbms_Output.put_line(

                   'Contents of ' || UPPER(tab)|| '.' || UPPER(col) ||

                   ' for ' || UPPER(dtcol) ||

                   ' between ' || dt1 || ' AND' || NVL (dt2, dt1+1));

    END IF;

   Dbms_Output.put_line(val);

  ENDLOOP;

 CLOSE cv;

END;

https://blog.csdn.net/keven2840/article/details/77870465/

 

 

 

 

 

oracle中游標與動態繫結變數

一、      遊標:

用資料庫語言來描述:遊標是對映在結果集中一行資料上的位置實體,有了遊標使用者就可以訪問結果集中的任意一行資料了,將遊標放置到某行後,即可對該行資料進行操作,例如提取當前行的資料等等。

在Oracle9i之前,使用FETCH語句每次只能提取一行資料;從Oracle9i開始,通過使用FETCH…BULK COLLECT INTO語句,每次可以提取多行資料。語法如下:

(1) FETCH cursor_name INTO variable1,variable2,…;

此方法必須要使用迴圈語句處理結果集的所有資料。

(2) FETCH cursor_name BULK COLLECT INTO collect1,collect2,…[LIMIT rows]

[LIMIT rows]可用來限制每次遊標每次提取的行數。

遊標的分類: 顯式遊標和隱式遊標

顯示遊標的使用:

  1. 宣告遊標

CURSOR mycur(vartype number) is

select emp_no,emp_zc from cus_emp_basic

where com_no = vartype;

  1. 開啟遊標

open mycur(000627) 注:000627:引數

  1. 讀取資料

fetch mycur into varno,varprice;

  1. 關閉遊標

close mycur;

遊標的屬性

oracle遊標有4個屬性: %ISOPEN 、%FOUND 、%NOTFOUND、%ROWCOUNT

  • %ISOPEN 判斷遊標是否被開啟,如果開啟%ISOPEN 等於true,否則等於false
  • %FOUND %NOTFOUND 判斷遊標所在的行是否有效,如果有效,則%FOUNDD等於true,否則等於false
  • %ROWCOUNT 返回當前位置為止遊標讀取的記錄行數。

二、      動態繫結變數

動態繫結變數解決Oracle應用程式可伸縮性的一個關鍵環節;而Oracle的共享池就決定了開發人員必須使用繫結變數;如果想要Oracle 執行減慢,甚至完全終止,那就可以不用繫結變數。

這裡舉例說明上述問題;

為了查詢一個員工代號是123,你可以這樣查詢:

select * from emp where empno=’123’;

你也可以這樣查詢:

select * from emp where empno=:empno;

象我們往常一樣,你查詢員工’123’一次以後,有可能再也不用;接著你有可能查詢員工’456’,然後查詢’789’等等;如果查詢使用象第一個查詢語句,你每次查詢都是一個新的查詢(我們叫它硬編碼的查詢方法);因此,Oracle每次必須分析,解析,安全檢查, 優化等等;

第二個查詢語句提供了繫結變數:empno,它的值在查詢執行時提供,查詢經過一次編譯後,查詢方案儲存在共享池中,可以用來檢索和重用;在效能和伸縮性方面,這兩者的差異是巨大的,甚至是驚人的;通俗點講,就不是一個級別;

第一個查詢使用的頻率越高,所消耗的系統硬體資源越大,從而降低了使用者的使用數量;它也會把優化好的其它查詢語句從共享池中踢出;就象一個老鼠壞了一鍋湯似的,系統的整體效能降低; 而執行繫結變數,提交相同物件的完全相同的查詢的使用者(這句話,大家聽起來比較難理解,隨後我會給出詳細的解釋),一次性使用就可重複使用,其效率不言耳語; 打個形象的比喻來說,第一個查詢就象一次性使用的筷子,而第二個查詢象是鐵筷子,只要洗乾淨,張三李四都能用,合理有效地使用了資源

動態繫結與靜態對比:

DECLARE

v_sql VARCHAR2(500);

BEGIN

--不使用繫結變數

/*FOR i IN 1..50000 LOOP

v_sql :='insert into t_temp values('||i||')';

EXECUTE IMMEDIATE v_sql;

END LOOP;*/

 

--使用繫結變數增加資料

FOR i IN 1..50000 LOOP

v_sql :='insert into t_temp values(:a)';

EXECUTE IMMEDIATE v_sql USING i;

END LOOP;

END;

--TRUNCATE TABLE t_temp;

動態查詢sql舉例:

--查詢的動態sql

DECLARE

  V_SQL    VARCHAR2(100);

  V_CURSOR SYS_REFCURSOR;

  V_EMP    EMP%ROWTYPE;

BEGIN

  V_SQL := 'select * from emp &條件';

  OPEN V_CURSOR FOR V_SQL;

  LOOP

    FETCH V_CURSOR INTO V_EMP;

    EXIT WHEN V_CURSOR%NOTFOUND;

    DBMS_OUTPUT.PUT_LINE(V_EMP.ENAME);

  END LOOP;

  CLOSE V_CURSOR;

END;

https://www.cnblogs.com/leafde/p/3830505.html

 

 

 

 

 

Oracle動態遊標入門一

2008年01月12日 09:50:00 xjzdr 閱讀數:18038

 

說明:下面的儲存過程在Oracle817下全部通過測試,編譯和執行均是正確的

一、最簡單的一個動態遊標:
CREATE OR REPLACE PROCEDURE test_cur
is
strSql1 varchar(1000);
TYPE TCUR IS REF CURSOR; 
CUR TCUR;
AC_WHERE VARCHAR2(100);
AC VARCHAR2(100); 
BEGIN
AC_WHERE := '(52228,52230)';
OPEN CUR FOR 'SELECT bill_id FROM bill_main WHERE bill_id IN '|| AC_WHERE;
LOOP
FETCH CUR INTO AC;
EXIT WHEN CUR%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(AC);

END LOOP;
CLOSE CUR;
end test_cur;

二、動態遊標中使用動態的SQL語句並執行:
CREATE OR REPLACE PROCEDURE test_cur
(
p_orgid_wins string
)
is
strSql1 varchar2(1000);
TYPE My_CurType IS REF CURSOR; 
CUR_1 My_CurType;--指示CUR_1的型別為My_CurType,而My_CurType是遊標型別
AC_WHERE VARCHAR2(100);
AC VARCHAR2(100); 
BEGIN
AC_WHERE := '(52228,52230)';
OPEN CUR_1 FOR 'SELECT bill_id FROM bill_main WHERE bill_id IN '|| AC_WHERE;--開啟動態遊標
LOOP
FETCH CUR_1 INTO AC;
EXIT WHEN CUR_1%NOTFOUND;
strSql1:='delete bill_main where bill_id='||AC;
DBMS_OUTPUT.PUT_LINE(strSql1);
DBMS_OUTPUT.PUT_LINE(AC);
execute immediate strSql1;--執行一個動態的SQL語句
commit;
END LOOP;
CLOSE CUR_1;
end test_cur;

三、動態遊標中執行動態DQL語句:
CREATE OR REPLACE PROCEDURE test_cur
(
p_orgid_wins string
)
is
strSql1 varchar2(1000);

strSql2 varchar2(1000);
TYPE My_CurType IS REF CURSOR; 
CUR_1 My_CurType;--指示CUR_1的型別為My_CurType,而My_CurType是遊標型別
AC_WHERE VARCHAR2(100);
t_to_orgid number;
t_bill_id number; 
BEGIN
AC_WHERE := '(98978,98980)';
strSql1:='SELECT bill_id,to_orgid FROM bill_main WHERE bill_id IN '|| AC_WHERE;
DBMS_OUTPUT.PUT_LINE(strSql1);
OPEN CUR_1 FOR strSql1;--開啟動態遊標
LOOP
FETCH CUR_1 INTO t_bill_id,t_to_orgid;
EXIT WHEN CUR_1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('t_to_orgid='||t_to_orgid);

strSql2:='delete bill_main where bill_id='||t_bill_id;

strSql2:=strSql2|| 'and start_no='||'16506';
DBMS_OUTPUT.PUT_LINE(strSql2);
DBMS_OUTPUT.PUT_LINE(t_bill_id);
execute immediate strSql1;--執行一個動態的SQL語句
commit;
END LOOP;
CLOSE CUR_1;
end test_cur; 

https://blog.csdn.net/xjzdr/article/details/2038904?utm_source=blogxgwz8

 

 

 

 

在Oracle中執行動態SQL的幾種方法

Oracle中執行動態SQL的幾種方法

在一般的sql操作中,sql語句基本上都是固定的,如:
SELECT t.empno,t.ename  FROM scott.emp t WHERE t.deptno = 20;
但有的時候,從應用的需要或程式的編寫出發,都可能需要用到動態SQl,如:
當 from 後的表 不確定時,或者where 後的條件不確定時,都需要用到動態SQL。

一、使用動態遊標實現
1、宣告動態遊標
TYPE i_cursor_type IS REF CURSOR;
2、宣告遊標變數
my_cursor i_cursor_type;
3、使用遊標
n_deptno:=20;
dyn_select := 'select empno,ename from emp where deptno='||n_deptno;
OPEN my_cursor FOR dyn_select;
LOOP 
  FETCH my_cursor INTO n_empno,v_ename;
  EXIT WHEN my_cursor%NOTFOUND;
  --用n_empno,v_ename做其它處理
  --....
END LOOP;
CLOSE dl_cursor;
4、小結:動態遊標可以勝任大多數動態SQL的需求了,使用簡潔方便居家旅行之必備殺人放火之法寶。

二、使用 EXECUTE IMMEDIATE
最早大家都使用DBMS_SQL包,但是太太麻煩了,最終都放棄了。但是自從有了EXECUTE IMMEDIATE之後,但要注意以下幾點:
EXECUTE IMMEDIATE代替了以前Oracle8i中DBMS_SQL package包.它解析並馬上執行動態的SQL語句或非執行時建立的PL/SQL塊.動態建立和執行SQL語句效能超前,EXECUTE IMMEDIATE的目標在於減小企業費用並獲得較高的效能,較之以前它相當容易編碼.儘管DBMS_SQL仍然可用,但是推薦使用EXECUTE IMMEDIATE,因為它獲的收益在包之上。 
 使用技巧

1. EXECUTE IMMEDIATE將不會提交一個DML事務執行,應該顯式提交
 如果通過EXECUTE IMMEDIATE處理DML命令,那麼在完成以前需要顯式提交或者作為EXECUTE IMMEDIATE自己的一部分. 如果通過EXECUTE IMMEDIATE處理DDL命令,它提交所有以前改變的資料

2. 不支援返回多行的查詢,這種互動將用臨時表來儲存記錄(參照例子如下)或者用REF cursors.

3. 當執行SQL語句時,不要用分號,當執行PL/SQL塊時,在其尾部用分號.

4. 在Oracle手冊中,未詳細覆蓋這些功能。下面的例子展示了所有用到Execute immediate的可能方面.希望能給你帶來方便.

5. 對於Forms開發者,當在PL/SQL 8.0.6.3.版本中,Forms 6i不能使用此功能.

EXECUTE IMMEDIATE用法例子

1. 在PL/SQL執行DDL語句


 begin
  execute immediate 'set role all';
 end;

2. 給動態語句傳值(USING 子句)


 declare
  l_depnam varchar2(20) := 'testing';
  l_loc    varchar2(10) := 'Dubai';
  begin
  execute immediate 'insert into dept values  (:1, :2, :3)'
    using 50, l_depnam, l_loc;
  commit;
 end;

3. 從動態語句檢索值(INTO子句)


 declare
  l_cnt    varchar2(20);
 begin
  execute immediate 'select count(1) from emp'
    into l_cnt;
  dbms_output.put_line(l_cnt);
 end;

4. 動態呼叫例程.例程中用到的繫結變數引數必須指定引數型別.黓認為IN型別,其它型別必須顯式指定

 declare
  l_routin   varchar2(100) := 'gen2161.get_rowcnt';
  l_tblnam   varchar2(20) := 'emp';
  l_cnt      number;
  l_status   varchar2(200);
 begin
  execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
    using in l_tblnam, out l_cnt, in out l_status;

  if l_status != 'OK' then
     dbms_output.put_line('error');
  end if;
 end;

5. 將返回值傳遞到PL/SQL記錄型別;同樣也可用%rowtype變數


 declare
    type empdtlrec is record (empno  number(4),ename  varchar2(20),deptno  number(2));
    empdtl empdtlrec;
 begin
    execute immediate 'select empno, ename, deptno '||'from emp where empno = 7934'
    into empdtl;
 end;

 

6. 傳遞並檢索值.INTO子句用在USING子句前

 declare
   l_dept    pls_integer := 20;
   l_nam     varchar2(20);
   l_loc     varchar2(20);
 begin
    execute immediate 'select dname, loc from dept where deptno = :1'
       into l_nam, l_loc
       using l_dept ;
 end;

7. 多行查詢選項.對此選項用insert語句填充臨時表,用臨時表進行進一步的處理,也可以用REF cursors糾正此缺憾.
 
 declare
  l_sal   pls_integer := 2000;
 begin
  execute immediate 'insert into temp(empno, ename) ' ||
                   '          select empno, ename from emp ' ||
                   '          where  sal > :1'
    using l_sal;
  commit;
 end;

       對於處理動態語句,EXECUTE IMMEDIATE比以前可能用到的更容易並且更高效.當意圖執行動態語句時,適當地處理異常更加重要.應該關注於捕獲所有可能的異常.

 

 

 

 

ORACLE 動態執行SQL語句

部落格分類:

SQLOracleCC++C# 

Oracle 動態SQL
Oracle 動態SQL有兩種寫法:用 DBMS_SQL 或 execute immediate,建議使用後者。試驗步驟如下:


1. DDL 和 DML

Sql程式碼  收藏程式碼

  1. /*** DDL ***/  
  2. begin  
  3.     EXECUTE IMMEDIATE 'drop table temp_1';  
  4.     EXECUTE IMMEDIATE 'create table temp_1(name varchar2(8))';  
  5. end;  
  6.   
  7. /*** DML ***/  
  8. declare  
  9.     v_1 varchar2(8);  
  10.     v_2 varchar2(10);  
  11.     str varchar2(50);  
  12. begin  
  13.     v_1:='測試人員';  
  14.     v_2:='北京';  
  15.     str := 'INSERT INTO test (name ,address) VALUES (:1, :2)';  
  16.     EXECUTE IMMEDIATE str USING v_1, v_2;  
  17.     commit;  
  18. end;  

 



2. 返回單條結果

Sql程式碼  收藏程式碼

  1. declare  
  2.     str varchar2(500);  
  3.     c_1 varchar2(10);  
  4.     r_1 test%rowtype;  
  5. begin  
  6.     c_1:='測試人員';  
  7.     str:='select * from test where name=:c WHERE ROWNUM=1';  
  8.     execute immediate str into r_1 using c_1;  
  9.     DBMS_OUTPUT.PUT_LINE(R_1.NAME||R_1.ADDRESS);  
  10. end ;  

 



3. 返回結果集

 

Sql程式碼  收藏程式碼

  1. CREATE OR REPLACE package pkg_test as  
  2.     /* 定義ref cursor型別  
  3.     不加return型別,為弱型別,允許動態sql查詢,  
  4.     否則為強型別,無法使用動態sql查詢;  
  5.     */  
  6.     type myrctype is ref cursor;  
  7.   
  8.     --函式申明  
  9.     function get(intID number) return myrctype;  
  10. end pkg_test;  
  11. /  
  12.   
  13. CREATE OR REPLACE package body pkg_test as  
  14. --函式體  
  15.     function get(intID number) return myrctype is  
  16.         rc myrctype; --定義ref cursor變數  
  17.         sqlstr varchar2(500);  
  18.     begin  
  19.         if intID=0 then  
  20.             --靜態測試,直接用select語句直接返回結果  
  21.             open rc for select id,name,sex,address,postcode,birthday from  
  22. student;  
  23.         else  
  24.             --動態sql賦值,用:w_id來申明該變數從外部獲得  
  25.             sqlstr := 'select id,name,sex,address,postcode,birthday from student  
  26. where id=:w_id';  
  27.             --動態測試,用sqlstr字串返回結果,用using關鍵詞傳遞引數  
  28.             open rc for sqlstr using intid;  
  29.         end if;  
  30.   
  31.         return rc;  
  32.     end get;  
  33.   
  34. end pkg_test;  
  35. /  

   

sql server 自定義函式的使用

自定義函式

 

使用者定義自定義函式像內建函式一樣返回標量值,也可以將結果集用表格變數返回

使用者自定義函式的型別:

標量函式:返回一個標量值

表格值函式{內聯表格值函式、多表格值函式}:返回行集(即返回多個值)

 

1、標量函式

Create function 函式名(引數)

Returns 返回值資料型別

[with {Encryption | Schemabinding }]

[as]

begin

SQL語句(必須有return 變數或值)

 

End

 

Schemabinding :將函式繫結到它引用的物件上(注:函式一旦繫結,則不能刪除、修改,除非刪除繫結)

 

 

Create function AvgResult(@scode varchar(10))

Returns real

As

Begin

   Declare @avg real

   Declare @code varchar(11)

   Set @[email protected] + ‘%’

   Select @avg=avg(result) from LearnResult_baijiali

Where scode like @code

Return @avg

End

 

執行使用者自定義函式

select 使用者名稱。函式名 as 欄位別名

select dbo.AvgResult(‘s0002’) as result

 

使用者自定義函式返回值可放到區域性變數中,用set ,select,exec賦值

declare @avg1 real ,@avg2 real ,@avg3 real

select @avg1= dbo.AvgResult(‘s0002’)

set @avg2= dbo.AvgResult(‘s0002’)

exec @avg3= dbo.AvgResult ‘s0002’

select @avg1 as avg1 ,@avg2 as avg2 ,@avg3 as avg3

 

函式引用

 

create function code(@scode varchar(10))

returns varchar(10)

as

begin

declare @ccode varchar(10)

set @scode = @scode + ‘%’

select @ccode=ccode from cmessage

   where ccode like @scode

return @ccode

end

 

select name from class where ccode = dbo.code(‘c001’)

 

2、表格值函式

a、 內聯表格值函式

格式:

create function 函式名(引數)

returns table

[with {Encryption | Schemabinding }]

as

return(一條SQL語句)

 

create function tabcmess(@code varchar(10))

returns table

as

return(select ccode,scode from cmessage where ccode like @ccode)

 

b、 多句表格值函式

   create function 函式名(引數)

   returns 表格變數名table (表格變數定義)

   [with {Encryption | Schemabinding }]

as

   begin

    SQL語句

   end

 

 多句表格值函式包含多條SQL語句,至少有一條在表格變數中填上資料值

 表格變數格式

returns @變數名 table (column 定義| 約束定義 [,…])

對錶格變數中的行可執行select,insert,update,delete , 但select into 和 insert 語句的結果集是從儲存過程插入。

 

Create function tabcmessalot (@code varchar(10))

Returns @ctable table(code varchar(10) null,cname varchar(100) null)

As

Begin

Insert @ctable

Select ccode,explain from cmessage

Where scode like @code

return

End

 

Select * from tabcmessalot(‘s0003’)

https://www.cnblogs.com/hanruyue/p/5974036.html