Oracle 動態遊標 PL/SQL 動態SQL語句 open for [using] 語句
PL/SQL:open for [using] 語句
2017年07月19日 09:52:55 學孩兒無牙哭做粥 閱讀數:681 標籤: oracleSQLPLSQL 更多
版權宣告:本文為博主原創文章,未經博主允許不得轉載。 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]可用來限制每次遊標每次提取的行數。
遊標的分類: 顯式遊標和隱式遊標
顯示遊標的使用:
- 宣告遊標
CURSOR mycur(vartype number) is
select emp_no,emp_zc from cus_emp_basic
where com_no = vartype;
- 開啟遊標
open mycur(000627) 注:000627:引數
- 讀取資料
fetch mycur into varno,varprice;
- 關閉遊標
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語句
部落格分類:
Oracle 動態SQL
Oracle 動態SQL有兩種寫法:用 DBMS_SQL 或 execute immediate,建議使用後者。試驗步驟如下:
1. DDL 和 DML
- /*** DDL ***/
- begin
- EXECUTE IMMEDIATE 'drop table temp_1';
- EXECUTE IMMEDIATE 'create table temp_1(name varchar2(8))';
- end;
- /*** DML ***/
- declare
- v_1 varchar2(8);
- v_2 varchar2(10);
- str varchar2(50);
- begin
- v_1:='測試人員';
- v_2:='北京';
- str := 'INSERT INTO test (name ,address) VALUES (:1, :2)';
- EXECUTE IMMEDIATE str USING v_1, v_2;
- commit;
- end;
2. 返回單條結果
- declare
- str varchar2(500);
- c_1 varchar2(10);
- r_1 test%rowtype;
- begin
- c_1:='測試人員';
- str:='select * from test where name=:c WHERE ROWNUM=1';
- execute immediate str into r_1 using c_1;
- DBMS_OUTPUT.PUT_LINE(R_1.NAME||R_1.ADDRESS);
- end ;
3. 返回結果集
- CREATE OR REPLACE package pkg_test as
- /* 定義ref cursor型別
- 不加return型別,為弱型別,允許動態sql查詢,
- 否則為強型別,無法使用動態sql查詢;
- */
- type myrctype is ref cursor;
- --函式申明
- function get(intID number) return myrctype;
- end pkg_test;
- /
- CREATE OR REPLACE package body pkg_test as
- --函式體
- function get(intID number) return myrctype is
- rc myrctype; --定義ref cursor變數
- sqlstr varchar2(500);
- begin
- if intID=0 then
- --靜態測試,直接用select語句直接返回結果
- open rc for select id,name,sex,address,postcode,birthday from
- student;
- else
- --動態sql賦值,用:w_id來申明該變數從外部獲得
- sqlstr := 'select id,name,sex,address,postcode,birthday from student
- where id=:w_id';
- --動態測試,用sqlstr字串返回結果,用using關鍵詞傳遞引數
- open rc for sqlstr using intid;
- end if;
- return rc;
- end get;
- end pkg_test;
- /
自定義函式
使用者定義自定義函式像內建函式一樣返回標量值,也可以將結果集用表格變數返回
使用者自定義函式的型別:
標量函式:返回一個標量值
表格值函式{內聯表格值函式、多表格值函式}:返回行集(即返回多個值)
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