c 呼叫儲存過程兩種方法

2022-03-08 23:35:06 字數 4644 閱讀 4287

摘要 儲存過程的呼叫在b/s系統中用的很多。傳統的呼叫方法不僅速度慢,而且**會隨著儲存過程的增多不斷膨脹,難以維護。新的方法在一定程度上解決了這些問題。

儲存過程簡介

簡單的說,儲存過程是由一些sql語句和控制語句組成的被封裝起來的過程,它駐留在資料庫中,可以被客戶應用程式呼叫,也可以從另乙個過程或觸發器呼叫。它的引數可以被傳遞和返回。與應用程式中的函式過程類似,儲存過程可以通過名字來呼叫,而且它們同樣有輸入引數和輸出引數。

根據返回值型別的不同,我們可以將儲存過程分為三類:返回記錄集的儲存過程, 返回數值的儲存過程(也可以稱為標量儲存過程),以及行為儲存過程。顧名思義,返回記錄集的儲存過程的執行結果是乙個記錄集,典型的例子是從資料庫中檢索出符合某乙個或幾個條件的記錄;返回數值的儲存過程執行完以後返回乙個值,例如在資料庫中執行乙個有返回值的函式或命令;最後,行為儲存過程僅僅是用來實現資料庫的某個功能,而沒有返回值,例如在資料庫中的更新和刪除操作。

使用儲存過程的好處

相對於直接使用sql語句,在應用程式中直接呼叫儲存過程有以下好處:

(1)減少網路通訊量。呼叫乙個行數不多的儲存過程與直接呼叫sql語句的網路通訊量可能不會有很大的差別,可是如果儲存過程包含上百行sql語句,那麼其效能絕對比一條一條的呼叫sql語句要高得多。

(2)執行速度更快。有兩個原因:首先,在儲存過程建立的時候,資料庫已經對其進行了一次解析和優化。其次,儲存過程一旦執行,在記憶體中就會保留乙份這個儲存過程,這樣下次再執行同樣的儲存過程時,可以從記憶體中直接呼叫。

(3)更強的適應性:由於儲存過程對資料庫的訪問是通過儲存過程來進行的,因此資料庫開發人員可以在不改動儲存過程介面的情況下對資料庫進行任何改動,而這些改動不會對應用程式造成影響。

(4) 布式工作:應用程式和資料庫的編碼工作可以分別獨立進行,而不會相互壓制。

由以上的分析可以看到,在應用程式中使用儲存過程是很有必要的。

兩種不同的儲存過程呼叫方法

為了突出新方法的優點,首先介紹一下在.net中呼叫儲存過程的「官方」方法。另外,本文的所有示例程式均工作於sqlserver資料庫上,其它情況類似,以後不再一一說明。本文所有例子均採用c#語言。

要在應用程式中訪問資料庫,一般性的步驟是:首先宣告乙個資料庫連線sqlconnection,然後宣告乙個資料庫命令sqlcommand,用來執行sql語句和儲存過程。有了這兩個物件後,就可以根據自己的需要採用不同的執行方式達到目的。需要補充的是,不要忘記在頁面上新增如下的引用語句:using system.data.sqlclient。

就執行儲存過程來說,如果執行的是第一類儲存過程,那麼就要用乙個dataadapter將結果填充到乙個dataset中,然後就可以使用資料網格控制項將結果呈現在頁面上了;如果執行的是第二和第三種儲存過程,則不需要此過程,只需要根據特定的返回判定操作是否成功完成即可。

(1)執行乙個沒有引數的儲存過程的**如下:

sqlconnection conn=new sqlconnection(「connectionstring」);

sqldataadapter da= new sqldataadapter();

da.selectcommand = new sqlcommand();

da.selectcommand.connection = conn;

da.selectcommand.commandtext = "nameofprocedure";

da.selectcommand.commandtype = commandtype.storedprocedure;

然後只要選擇適當的方式執行此處過程,用於不同的目的即可。

(2)執行乙個有引數的儲存過程的**如下(我們可以將呼叫儲存過程的函式宣告為exeprocedure(string inputdate)):

sqlconnection conn=new sqlconnection(「connectionstring」);

sqldataadapter da = new sqldataadapter();

da.selectcommand = new sqlcommand();

da.selectcommand.connection = conn;

da.selectcommand.commandtext = "nameofprocedure";

da.selectcommand.commandtype = commandtype.storedprocedure;

(以上**相同,以下為要新增的**)

param = new sqlparameter("@parametername", sqldbtype.datetime);

param.direction = parameterdirection.input;

param.value = convert.todatetime(inputdate);

da.selectcommand.parameters.add(param);

這樣就新增了乙個輸入引數。若需要新增輸出引數:

//設定儲存過程的引數值,其中@parametername為儲存過程的引數.

param = new sqlparameter("@parametername", sqldbtype.datetime);

param.direction = parameterdirection.output;

param.value = convert.todatetime(inputdate); //儲存過程引數值;

da.selectcommand.parameters.add(param);

若要獲得參儲過程的返回值:

param = new sqlparameter("@parametername", sqldbtype.datetime);

param.direction = parameterdirection.returnvalue;

param.value = convert.todatetime(inputdate);

da.selectcommand.parameters.add(param);

執行: dataset myds=new dataset();

da.fill(myds,"tablename");

從上面的**我們可以看出,當儲存過程比較多或者儲存過程的引數比較多時,這種方法會大大影響開發的速度;另外一方面,如果專案比較大,那麼這些用於資料庫邏輯的函式在以後的維護中也是乙個很大的負擔。那麼,有沒有一種改進的方法可以解決這個問題呢?想到在執行沒有引數的儲存過程時只需要傳入乙個儲存過程的名字就可以呼叫相應的儲存過程,而且在sqlserver資料庫中我們可以直接在查詢分析器中敲入「儲存過程名(引數列表)」樣的字串就可以執行儲存過程,那麼,是否可以把這種思想應用到應用程式中呢?

於是在編譯器中鍵入相應**。這些**是在呼叫不帶引數的儲存過程的**的基礎上改的。具體**如下:

sqlconnection conn=new sqlconnection(「connectionstring」);

sqldataadapter da = new sqldataadapter();

da.selectcommand = new sqlcommand();

da.selectcommand.connection = conn;

da.selectcommand.commandtext = "nameofprocedure(』para1』,』para2』,para3)";

da.selectcommand.commandtype = commandtype.storedprocedure;

為了使**更具有代表性,要呼叫的儲存過程的第乙個和第二個引數都為字串型別,第三個引數為整型。執行以後發現,完全可以達到預期的效果!

兩種呼叫方法的比較

通過比較我們可以看到,第二種方法具有乙個很明顯的優點,那就是可以提高開發速度,節省開發時間,而且**容易維護,在一定程度上也減少了系統大小。但是,由於對儲存過程引數的處理比較籠統,如果要獲取輸出引數或者得到儲存過程的返回值,這種方法就不能滿足需要了。雖然如此,但是,這種方法畢竟可以讓開發人員少些很大一部分的**。如果不需要獲取輸出引數和返回值,那麼幾乎可以做到「一勞永逸」。因此在實際的程式開發中,這種方法還是具有一定的實用價值的。

用來建立dataread的儲存過程呼叫;

//資料庫連線字串

string connstr="server=localhost;database=stuims;uid=sa;pwd=admin";

//建立連線

sqlconnection conn=new sqlconnection(connstr);

//建立查詢命令

sqlcommand mycommand=new sqlcommand("儲存過程名",conn);

//呼叫儲存過程名

mycommand.commandtype=commandtype.storedprocedure;

//設定儲存過程的引數值,其中@id 為儲存過程的引數.

sqlparameter id=mycommand.parameters.add("@id",sqldbtype.ntext);

id.value=儲存過程引數值;

//執行命令

sqldatareader reader=mycommand.executereader();//讀取資料

//或者

sqldatareader reader=mycommand.executenonquery();//資料更新

**:

C 呼叫Python的兩種方法

public void pytest string paths string join lib environment.setenvironmentvariable pythonpath paths,environmentvariabletarget.process using py.gil ini...

兩種不同的儲存過程呼叫方法

兩種不同的儲存過程呼叫方法 為了突出新方法的優點,首先介紹一下在.net中呼叫儲存過程的 官方 方法。另外,本文的所有示例程式均工作於sqlserver資料庫上,其它情況類似,以後不再一一說明。本文所有例子均採用c 語言。要在應用程式中訪問資料庫,一般性的步驟是 首先宣告乙個資料庫連線sqlconn...

delphi呼叫cmd的兩種方法

delphi呼叫cmd的兩種方法 2008年10月01日 星期三 12 22 1 var s string begin s cmd.exe c edit1.text c 1.txt winexec pchar s sw hide sleep 2000 memo1.lines.loadfromfile...