c存儲過程返回多個
1. 存儲過程中調用帶返回值的函數
如果是ACCESS、Mysql、SQL 2000 資料庫
SELECT * FROM tabel_ WHERE date < (now()-30)
資料庫都自帶很多函數的
2. mysql 與oracle中的存儲過程及函數有什麼區別,盡可能詳細哦
本質上沒區別。只是函數有如:只能返回一個變數的限制。而存儲過程可以返回多個。而函數是可以嵌入在sql中使用的,可以在select中調用,而存儲過程不行。執行的本質都一樣。
函數限制比較多,比如不能用臨時表,只能用表變數.還有一些函數都不可用等等.而存儲過程的限制相對就比較少
由於我現在基本上是DBA的工作,因此平時也看一些資料庫方面的書籍。但是我一直對存儲過程和函數之間的區別掌握不透。我向來認為存儲過程可以實現的操作,函數也一樣可以實現。最近,剛好大學的老師給我們上SQL-Server的課程,我對這個問題的疑惑終於慢慢解開。今天晚上順便看了些網上的資料,覺得以下分析比較合理:
1. 一般來說,存儲過程實現的功能要復雜一點,而函數的實現的功能針對性比較強。
2. 對於存儲過程來說可以返回參數,而函數只能返回值或者表對象。
3. 存儲過程一般是作為一個獨立的部分來執行,而函數可以作為查詢語句的一個部分來調用,由於函數可以返回一個表對象,因此它可以在查詢語句中位於FROM關鍵字的後面。
4. 當存儲過程和函數被執行的時候,SQL Manager會到procere cache中去取相應的查詢語句,如果在procere cache里沒有相應的查詢語句,SQL Manager就會對存儲過程和函數進行編譯。
Procere cache中保存的是執行計劃 (execution plan) ,當編譯好之後就執行procere cache中的execution plan,之後SQL SERVER會根據每個execution plan的實際情況來考慮是否要在cache中保存這個plan,評判的標准一個是這個execution plan可能被使用的頻率;其次是生成這個plan的代價,也就是編譯的耗時。保存在cache中的plan在下次執行時就不用再編譯了。
存儲過程和用戶自定義函數具體的區別
存儲過程
存儲過程可以使得對資料庫的管理、以及顯示關於資料庫及其用戶信息的工作容易得多。存儲過程是 SQL 語句和可選控制流語句的預編譯集合,以一個名稱存儲並作為一個單元處理。存儲過程存儲在資料庫內,可由應用程序通過一個調用執行,而且允許用戶聲明變數、有條件執行以及其它強大的編程功能。
存儲過程可包含程序流、邏輯以及對資料庫的查詢。它們可以接受參數、輸出參數、返回單個或多個結果集以及返回值。
可以出於任何使用 SQL 語句的目的來使用存儲過程,它具有以下優點:
可以在單個存儲過程中執行一系列 SQL 語句。
可以從自己的存儲過程內引用其它存儲過程,這可以簡化一系列復雜語句。
存儲過程在創建時即在伺服器上進行編譯,所以執行起來比單個 SQL 語句快。
用戶定義函數
函數是由一個或多個 Transact-SQL 語句組成的子程序,可用於封裝代碼以便重新使用。Microsoft? SQL Server? 2000 並不將用戶限制在定義為 Transact-SQL 語言一部分的內置函數上,而是允許用戶創建自己的用戶定義函數。
可使用 CREATE FUNCTION 語句創建、使用 ALTER FUNCTION 語句修改、以及使用 DROP FUNCTION 語句除去用戶定義函數。每個完全合法的用戶定義函數名 (database_name.owner_name.function_name) 必須唯一。
必須被授予 CREATE FUNCTION 許可權才能創建、修改或除去用戶定義函數。不是所有者的用戶在 Transact-SQL 語句中使用某個函數之前,必須先給此用戶授予該函數的適當許可權。若要創建或更改在 CHECK 約束、DEFAULT 子句或計算列定義中引用用戶定義函數的表,還必須具有函數的 REFERENCES 許可權。
函數中的有效語句類型包括:
DECLARE 語句,該語句可用於定義函數局部的數據變數和游標。
為函數局部對象賦值,如使用 SET 給標量和表局部變數賦值。
游標操作,該操作引用在函數中聲明、打開、關閉和釋放的局部游標。不允許使用 FETCH 語句將數據返回到客戶端。僅允許使用 FETCH 語句通過 INTO 子句給局部變數賦值。
控制流語句。
SELECT 語句,該語句包含帶有表達式的選擇列表,其中的表達式將值賦予函數的局部變數。
INSERT、UPDATE 和 DELETE 語句,這些語句修改函數的局部 table 變數。
EXECUTE 語句,該語句調用擴展存儲過程。
在查詢中指定的函數的實際執行次數在優化器生成的執行計劃間可能不同。示例為 WHERE 子句中的子查詢喚醒調用的函數。子查詢及其函數執行的次數會因優化器選擇的訪問路徑而異
3. 該如何寫存儲過程,實現mysql返回多個結果,其中的結果可能為空
就跟寫Java代碼里有返回值的方法一樣,只是把語法換成Sql裡面的寫法就好了
aaa: 輸入參數
bbb: 輸出參數,一個表對象,或者一個結果集
包
proce getMySqlDate(aaa IN varchar2,
bbb OUT tmpTable%ROWTYPE) IS
本體
proce getMySqlDate(aaa IN varchar2,
bbb OUT tmpTable%ROWTYPE)
begin
--查詢數據
CURSOR curCc is
select a,b from tab1;
type typeCurCc of table curCc%ROWTYPE;
typeCurCc tabCurCc; -- 定義游標類型
--打開游標把查詢處理的數據,賦值到bbb的輸出參數就行了。
open 游標
....
bbb.a = 游標.a;
close 游標;
--存儲過程終了
END getMysql;
4. 如何調用一個Oracle存儲過程返回一個或多個REF游標,使用ADO從C
代碼如下:
CREATE OR REPLACE PROCEDURE P_TESTB
AS
VARCURSOR SYS_REFCURSOR;
R USERS%ROWTYPE;
BEGIN
P_TESTA(VARCURSOR);
LOOP
FETCH VARCURSOR INTO R;
EXIT WHEN
VARCURSOR%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(R.NAME);
END LOOP;
END
P_TESTB;
5. 1,存儲過程和函數的區別
存儲過程和函數目的是為了 可重復地 執行操作資料庫的sql語句的集合。
區別是寫法和調用上。
寫法上:存儲過程的參數列表可以有輸入參數、輸出參數、可輸入輸出的參數;
函數的參數列表只有輸入參數,並且有return <返回值類型,無長度說明>。
返回值上:
存儲過程的返回值,可以有多個值,
函數的返回值,只有一個值。
調用方式上:
存儲過程的調用方式有:
1)、exec <過程名>;
2)、execute <過程名>;
3)、在PL/SQL語句塊中直接調用。
函數的調用方式有:
在PL/SQL語句塊中直接調用。
具體分為:
----調用FUNCTION add_three_numbers
----1. 位置表示法調用函數
BEGIN
dbms_output.put_line(add_three_numbers(2,4,5));
END;
----2. 命名表示法調用函數
BEGIN
dbms_output.put_line(add_three_numbers(b=>3, a=>4,c=>2));
END;
----3. 混合使用位置表示法和命名表示法調用函數
BEGIN
dbms_output.put_line(add_three_numbers(3, b=>4,c=>2));
END;
----4. 排除表示法
BEGIN
dbms_output.put_line(add_three_numbers(12,c=>2));
END;
----5. sql調用表示法 --混合表示法
SELECT add_three_numbers(3, b=>4,c=>2) FROM DUAL;
----1. 該函數接受3個可選參數,返回3個數字的和
CREATE OR REPLACE FUNCTION add_three_numbers
(
a NUMBER:=0, b NUMBER:=0, c NUMBER:=0
)
RETURN NUMBER IS
BEGIN
RETURN a+b+c;
END;
存儲過程:
基本語法:
create procere <過程名>(<參數列表,無參時忽略>)
as|is
變數聲明、初始化
begin
業務處理、邏輯代碼
exception
異常捕獲、容錯處理
end <過程名>;
參數:<參數名> in|out|in out <參數類型,無長度說明> ,如:v_name varchar2
in:入參
out:出參
in out:出入參
註:as|is表示as或is
調用語法:
1)、exec <過程名>;
2)、execute <過程名>;
3)、在PL/SQL語句塊中直接調用。
例:
create or replace procere up_wap(v_param1 in out varchar2,v_param2 in out varchar2)
is
v_temp varchar2(20);
begin
dbms_output.put_line('交換前參數1:'||v_param1||' 參數2:'||v_param2);
v_temp:=v_param1;
v_param1:=v_param2;
v_param2:=v_temp;
dbms_output.put_line('交換後參數1:'||v_param1||' 參數2:'||v_param2);
exception
when others then dbms_output.put_line('There is a error when the procere up_wap executing!');
end up_wap;
/
-- 調用存儲過程
declare
v_param1 varchar2(20):='param1';
v_param2 varchar2(20):='param2';
begin
up_wap(v_param1 => v_param1,v_param2 => v_param2);
end;
/
自定義函數(function)
基本語法:
create function <函數名>(<參數列表,無參時忽略>)
return <返回值類型,無長度說明>
as|is
變數聲明、初始化
begin
業務處理、邏輯代碼
return <返回的值>;
exception
異常捕獲、容錯處理
end <函數名>;
參數:in 入參
註:只有入參的類型。
在存儲過程和自定義函數中的參數的傳遞(入參和出參)不能使用%type或%rowtype匹配,不能使用空值null,但是存儲過程可以返回空值。
例:
create function uf_select_name_by_id_test(v_id in number)
return varchar2
is
v_name t_test.t_name%type;
begin
select t_name into v_name from t_test where t_id=v_id;
return v_name;
exception
when others then dbms_output.put_line('error');
end uf_select_name_by_id_test;
/
select uf_select_name_by_id_test(1) 姓名 from al;-- select調用
declare --pl/sql語句塊調用
v_name varchar2(20);
begin
v_name:=uf_select_name_by_id_test(1);
dbms_output.put_line('name = '||v_name);
end;
/
6. 如何使用存儲過程返回行集
簡單的說,就是在對象模型中創建一個函數,讓其映射到資料庫中的存儲過程。然後通過調用對象模型中的這個函數達到調用映射的那個存儲過程的目的。
此演示代碼首先給出了測試中用到的存儲過程的定義,然後是映射函數的定義,同時也給出了結果類的代碼。最後是調用函數並顯示結果的代碼。
存儲過程的定義:
[vb] view plain
01.CREATE PROCEDURE [dbo].[CustomersByCity]
02. (@City NVARCHAR(20))
03.AS
04.BEGIN
05. -- SET NOCOUNT ON added to prevent extra result sets from
06. -- interfering with SELECT statements.
07. SET NOCOUNT ON;
08. SELECT CustomerID, ContactName, ContactTitle, City from Customers
09. as c where c.City=@City
10.END
映射到存儲過程的函數如下:
[c-sharp] view plain
01.[Function(Name="dbo.CustomersByCity")]
02.public ISingleResult<CustomersByCityResult> CustomersByCity(
03. [Parameter(Name="City", DbType="NVarChar(20)")] string city)
04.{
05. IExecuteResult result = this.ExecuteMethodCall(this,
06. ((MethodInfo)(MethodInfo.GetCurrentMethod())), city);
07. return ((ISingleResult<CustomersByCityResult>)(result.ReturnValue));
08.}
結果類的定義如下,如果你注意觀察的話,一定會發現結果類的列成員和存儲過程中查詢的數據列是相對應:
[c-sharp] view plain
01.[DataContract()]
02.public partial class CustomersByCityResult
03.{
04.
05. private string _CustomerID;
06.
07. private string _ContactName;
08.
09. private string _ContactTitle;
10.
11. private string _City;
12.
13. public CustomersByCityResult()
14. {
15. }
16.
17. [Column(Storage="_CustomerID", DbType="NChar(5) NOT NULL", CanBeNull=false)]
18. [DataMember(Order=1)]
19. public string CustomerID
20. {
21. get
22. {
23. return this._CustomerID;
24. }
25. set
26. {
27. if ((this._CustomerID != value))
28. {
29. this._CustomerID = value;
30. }
31. }
32. }
33.
34. [Column(Storage="_ContactName", DbType="NVarChar(30)")]
35. [DataMember(Order=2)]
36. public string ContactName
37. {
38. get
39. {
40. return this._ContactName;
41. }
42. set
43. {
44. if ((this._ContactName != value))
45. {
46. this._ContactName = value;
47. }
48. }
49. }
50.
51. [Column(Storage="_ContactTitle", DbType="NVarChar(30)")]
52. [DataMember(Order=3)]
53. public string ContactTitle
54. {
55. get
56. {
57. return this._ContactTitle;
58. }
59. set
60. {
61. if ((this._ContactTitle != value))
62. {
63. this._ContactTitle = value;
64. }
65. }
66. }
67.
68. [Column(Storage="_City", DbType="NVarChar(15)")]
69. [DataMember(Order=4)]
70. public string City
71. {
72. get
73. {
74. return this._City;
75. }
76. set
77. {
78. if ((this._City != value))
79. {
80. this._City = value;
81. }
82. }
83. }
84.}
7. 如何在存儲過程中直接使用另一個存儲過程返回的數據集
resultset
rs
=
cstmt.executequery();
callablestatement
自身就有一個返回是個結果集的方法
然後你可以通過循環resultset
封裝你的數據
8. C#獲取 sqlserver 存儲過程返回多表數據
返回的時候用dataset就可以,比如你存儲過程這樣寫
select * from A
select * from B
select * from C
select * from D
select * from D
在執行完存儲過程後返回一個dataset
dataset ds = 執行存儲過程
ds.tables[0]就是表A
ds.tables[1]就是表B
ds.tables[2]就是表C
剩下的依次類推.
9. sqlserver存儲過程中有多個insert和select,如何只獲得想要的返回集
@id INT, @value VARCHAR(10);BEGIN -- 定義游標. DECLARE c_test_main CURSOR FAST_FORWARD FOR SELECT id,valueFROM test_main; -- 打開游標. OPEN c_test_main; WHILE 1=1 BEGIN -- 填充數據. FETCH NEXT FROM c_test_main INTO @id, @value; -- 假如未檢索到數據,退出循環. IF@@fetch_status!= 0 BREAK; PRINT @value; END; -- 關閉游標 CLOSE c_test_main; -- 釋放游標. DEALLOCATE c_test_main;END;
10. 如何在mysql存儲過程中處理select語句返回的多行結果
CREATE PROCEDURE curdemo()BEGIN DECLARE done INT DEFAULT 0; DECLARE a CHAR(16); DECLARE b,c INT; DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1; DECLARE cur2 CURSOR FOR SELECT i FROM test.t2; DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; OPEN cur1; OPEN cur2; REPEAT FETCH cur1 INTO a, b; FETCH cur2 INTO c; IF NOT done THEN IF b < c THEN INSERT INTO test.t3 VALUES (a,b); ELSE INSERT INTO test.t3 VALUES (a,c); END IF; END IF; UNTIL done END REPEAT; CLOSE cur1; CLOSE cur2;END