預存程序和SQL語句比較及預存程序在C#中調用方法

來源:互聯網
上載者:User

做為SQL預存程序和.NET的新手,下面的指導還是很有用的,自己這一段剛剛接觸這些東西,搜集了一些相關的東西,能使新手較容易上手,當然啦,
要精通和熟練應用,還是要看更多更深的資料的,高手請不要見笑。
以下內容均來自網路,只供參考學習:
--------

儲過程與SQL語句的恩怨情仇


程式員說:預存程序還是SQL語句,這是一個問題。
江湖現在有三個流派,一個是SQL
語句流的,崇尚使用SQL語句,一派是預存程序派的,崇尚用預存程序說話,還有一派是中庸派的,講求和諧,所以也就前兩派吵得厲害,中庸派的看熱鬧。現在
SQL派的有Nhibernate為首的眾多ORM助陣,最近風生水起比較得意,預存程序派也有自己的殺手秘籍,兩派互不相讓,爭鬥由來已久。

儲過程派的追求速度,所謂天下無功無堅不破,唯快不破,這也是預存程序派的人行走江湖的最大本錢。之前預存程序派的攻擊SQL語句派的還有一個秘籍就是安
全,不過現在都沒人用串連String的動態SQL的了,這招也就失效了。
SQL語句派是資格很老的流派,但是新手居多,老資格很多投奔敵營儲存
過程派了。Java幫的人很多都是SQL語句派的,而預存程序派的以微軟幫的居多。
不過預存程序派也有軟肋,可移植性就是其一,還有一點就是可擴
展性,因為一般大型的Web應用程式都是多Web伺服器,然後用雙資料庫伺服器做雙機熱備,其中一台開機,但是是閑置的,這裡只是解決單點故障的問題,但
是形成了多Web應用伺服器,單資料庫伺服器的情況,如果所有的運算都用預存程序實現,那麼會造成資料庫伺服器負擔過重,而Web伺服器負荷不足的情況,
而擴充資料庫伺服器的話就會非常的麻煩,而且投資較大,程式也需要改,而投資Web伺服器就相對便宜而且擴容更加簡單。
人在江湖漂哪有不挨刀,所
以中庸一點比較保險,我比較傾向於用把較多的負擔放到程式裡來,而降低資料庫得負擔,因為只要資料庫扛得住,再增加Web伺服器那是比較容易的,但是一旦
資料庫伺服器扛不住了我們就只有哭了。一般報表阿,還有一些結果集比較複雜的我就用預存程序來封裝,一般的查詢和CUID操作我都是找個ORM來搞定。

其實主要是在說預存程序的軟肋。
1)從部署上看,預存程序要比sql難
2) 從效能看,預存程序要比SQL高
3)
從安全性將,預存程序比SQL防注入
過程可以減少網路資料轉送量,把計算都放在伺服器上   
    
前端程式可以直接存取資料
庫的表,可以直接用SQL語言直接對資料庫的表進行讀寫操作;   
    
 為安全,可以編程,使用預存程序進行資料表的讀寫操作,而
前端程式直接存取這些預存程序,而不是資料庫的表;   
    
更安全的方法是:在前端程式和資料庫之間,增加資料庫訪問層;前端將數
據的讀寫請求提交給中介層,有中介層與資料庫連接進行資料庫的實際操作,將結果送給前端,這種方式可以避免前端機器直接連接到資料庫的可能,資料庫更安
全。

 C#兩種不同的預存程序調用方法

====================================================

兩種不同的預存程序調用方法
為了突出新方法的優點,首先介紹一下在.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);
 
 這樣就添加了一個輸入參數。若需要添加輸出參數:

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);
 
 從上面的代碼我們可以看出,當預存程序比較多或者預存程序的參數比較多時,這種方法會大大影響開發的速度;另外一方面,如果項目比較大,那麼這些用於數
據庫邏輯的函數在以後的維護中也是一個很大的負擔。那麼,有沒有一種改進的方法可以解決這個問題呢?想到在執行沒有參數的預存程序時只需要傳入一個儲存過
程的名字就可以調用相應的預存程序,而且在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;
  為了使代碼更具有代表性,要調用的預存程序的第一個和第二個參數都為字串
類型,第三個參數為整型。執行以後發現,完全可以達到預期的效果!

SQL Server
2005協助文檔中關於預存程序傳回值使用的例子和說明

RETURN
語句無條件終止查詢、預存程序或批處理。預存程序或批處理中 RETURN 語句後面的語句都不執行。

當在預存程序中使用 RETURN 語句時,此語句可以指定返回給調用應用程式、批處理或過程的整數值。如果 RETURN
未指定值,則預存程序返回 0。

大多數預存程序按常規使用傳回碼表示預存程序的成功或失敗。沒有發生錯誤時預存程序傳回值 0。任何非零值表示有錯誤發生。例如:

USE
AdventureWorks;
GO
-- Create a procedure that takes one input
parameter
-- and returns one output parameter and a return code.
CREATE
PROCEDURE SampleProcedure @EmployeeIDParm INT,
    @MaxTotal INT
OUTPUT
AS
-- Declare and initialize a variable to hold @@ERROR.
DECLARE
@ErrorSave int;
SET @ErrorSave = 0;
-- Do a SELECT using the
input parameter.
SELECT c.FirstName, c.LastName, e.Title
FROM
HumanResources.Employee AS e
JOIN Person.Contact AS c ON e.ContactID =
c.ContactID
WHERE EmployeeID = @EmployeeIDParm;
-- Save any
nonzero @@ERROR value.
IF (@@ERROR <> 0)
    SET @ErrorSave =
@@ERROR;
-- Set a value in the output parameter.
SELECT @MaxTotal
= MAX(TotalDue)
FROM Sales.SalesOrderHeader;
IF (@@ERROR <>
0)
    SET @ErrorSave = @@ERROR;
-- Returns 0 if neither SELECT
statement had
-- an error, otherwise returns the last error.
RETURN
@ErrorSave;
GO

執行預存程序的 Transact-SQL 批處理或預存程序可以將傳回碼檢索到整數變數中:

DECLARE
@ReturnStatus int;
DECLARE @MaxTotalVariable int;
DECLARE
@MaxTotal int;
EXECUTE @ReturnStatus = SampleProcedure
@EmployeeIDParm = 65 ,@MaxTotal = @MaxTotalVariable OUTPUT;
PRINT '
';
PRINT 'Return code = ' + CAST(@ReturnStatus AS CHAR(10));
PRINT
'Maximum Order Total = ' + CAST(@MaxTotalVariable AS CHAR(15));
GO

調用預存程序的應用程式可以將傳回碼所對應的參數標記與整型變數綁定。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.