文章出處

上一篇貌似少介紹了自定義函數和存儲過程, 因為這兩個也可以使用查詢的方式來實現功能, 這一篇就補上

 一、自定義函數的創建和調用 (mysql的)

Delimiter $$
drop function if exists func_test;
CREATE FUNCTION func_test (idIn INT) RETURNS int
BEGIN
DECLARE res int DEFAULT 0;
select count(1) into res from tch_teacher where id > idIn ;
return res;
END $$
Delimiter ;

注意在mysql中, delimiter $$ 這個的使用, 起一個分割功能, 有些編譯器中, 如果不寫這個, 是不會把這些當做方法,存儲過程去處理的, 而是當做普通查詢語句, 會報錯的.

以下是調用方法:

//方法一 : 直接寫sql, 然后用Query調用
sql = "select func_test(@id);";
var res = conn.Query<int>(sql, new { id = 10 }).FirstOrDefault();  //90
Console.WriteLine("Count = " + res); //Count = 90

//方法二 : 直接用Query方法, 傳入函數名, 參數, 但是注意要把CommondType設置為StoredProcedure
//而且調用的時候, 是必須要有 Return參數的, 否則會報錯
var para = new  DynamicParameters();
para.Add("@idIn", 20);
para.Add("@res", 0, DbType.Int32, ParameterDirection.ReturnValue);
var res1 = conn.Query("func_test", para, null, true, null, CommandType.StoredProcedure).FirstOrDefault();  //0
Console.WriteLine("Query @res = " + para.Get<int>("@res"));  //Query @res = 80

//方法三 : 使用Execute方法也是可以的, 要注意加一個返回參數
var param = new DynamicParameters();
param.Add("@idIn", 25);
param.Add("@res", 0, DbType.Int32, ParameterDirection.ReturnValue);
var res2 = conn.Execute("func_test", param, null, null, CommandType.StoredProcedure);  //0
Console.WriteLine("Execute @res = " + param.Get<int>("@res"));  //Execute @res = 75

一般來說, 我習慣使用方法一, 比較方便, 因為函數這里并沒有返回參數, 在使用時, 不需要在sql中定義參數, 然后執行. 方法一是很方便的

此種方法在調用存儲過程的時候也可以符合部分情況. 請看下面分解

 

二、存儲過程的創建和調用

Delimiter $$
drop PROCEDURE if EXISTS pro_test;
create PROCEDURE pro_test(in idIn int)
begin
select count(1) as Count from tch_teacher where id > idIn;
end $$
Delimiter ;

Delimiter $$
drop PROCEDURE if EXISTS pro_test1;
create PROCEDURE pro_test1(in idIn int, out count int)
begin
select count(1) into count from tch_teacher where id > idIn;
select * from tch_teacher where id > idIn;
end $$
Delimiter ;

call pro_test(11);

set @count =0;
call pro_test1(11, @count);
select @count;

 

這里我創建了兩個存儲過程, 一個是有返回參數的, 另一個并沒有.

//方法一
sql = "call pro_test(@id);";
var res = conn.Query<int>(sql, new { id = 15 }).FirstOrDefault();  //85
Console.WriteLine("res = " + res);  //res = 85

//方法二
var param = new DynamicParameters();
param.Add("@idIn", 20);
param.Add("@count", 0, DbType.Int32, ParameterDirection.Output);
var res2 = conn.Query<Tch_Teacher>("pro_test1", param, null, true, null, CommandType.StoredProcedure);//res2.Count = 80
Console.WriteLine("Query count = " + param.Get<object>("@count"));   //Query count = 80

//方法三
var res3 = conn.Execute("pro_test1", param, null, null, CommandType.StoredProcedure); //0
Console.WriteLine("Execute count = " + param.Get<object>("@count"));  //Execute count = 80

如果存儲過程有輸入參數, 那么方法一并不適用, 會報錯的. Dapper解析到"@count"的時候, 會報錯.

所以, 對于存儲過程, 推薦適用方法二, 當然, 在沒有輸出參數的時候, 方法一更為簡單粗暴.

 


文章列表




Avast logo

Avast 防毒軟體已檢查此封電子郵件的病毒。
www.avast.com


arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()