文章編號: 308049 - 上次校閱: 2007年8月17日 - 版次: 3.2

HOW TO:使用 ADO.NET 及 Visual Basic .NET 呼叫參數化的預存程序

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

您可以利用數種方法,使用 ADO.NET 來呼叫預存程序,以及取回傳回值並傳回參數,方法如下:
  • 使用 DataSet 物件蒐集傳回的資料列,並與這些資料列以及傳回值和傳回參數搭配使用。
  • 使用 DataReader 物件蒐集傳回的資料列、在這些資料列之間移動,以及蒐集傳回值和傳回參數。
  • 使用 ExecuteScalar 方法傳回結果中第一筆資料列的第一個資料行中的值,以及傳回值和傳回參數。 這個方法與彙總函式搭配使用會特別有用。
  • 使用 ExecuteNonQuery 方法,可以只傳回傳回參數和傳回值。任何傳回的資料列都會被捨棄。這對執行動作查詢,特別有幫助。
本文將示範後面三種方法,並且一起使用 SqlCommandOleDbCommand 物件。請確認您只複製了所使用 Managed 提供者的程式碼。如果您不確定可以使用哪些 Managed 提供者,請造訪下列 Microsoft Developer Network 網站:
.NET 資料提供者 (英文)
http://msdn2.microsoft.com/en-us/library/a6cd7c08(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/a6cd7c08(vs.71).aspx)
本文的每個範例都會將參數新增至 Command 物件的 Parameters 集合中。使用 SqlCommand 物件時,不必依照任何特定的順序來新增參數,但是參數的名稱必須是正確的。使用 OleDbCommand 物件時,必須以正確的順序新增參數,並且不可以依照名稱順序來使用參數。

使用 DataReader 傳回資料列及參數

您可以使用 DataReader 物件傳回唯讀且順向的資料流。DataReader 所包含的資訊來自預存程序。本範例使用 DataReader 物件執行具有輸入和輸出參數的預存程序,然後在傳回的記錄之間移動,以檢視傳回的參數。
  1. 在執行 Microsoft SQL Server 的伺服器上建立下列預存程序:
    Create Procedure TestProcedure
      (
         @au_idIN varchar (11),
         @numTitlesOUT Integer OUTPUT
      )
    As
    
    select A.au_fname, A.au_lname, T.title 
    from authors as A join titleauthor as TA on
    A.au_id=TA.au_id
    join titles as T
    on T.title_id=TA.title_id
    where A.au_id=@au_idIN
    set @numTitlesOUT = @@Rowcount
    return (5) 
    					
  2. SystemSystem.Data 命名空間上使用 Imports 陳述式,如此您就不必在後面的程式碼中限定這些命名空間的宣告。您必須先使用 Imports 陳述式,再限定任何其他宣告。請確認您只複製已選擇之提供者的程式碼。SQL 用戶端
    Imports System.Data.SqlClient					
    OLE DB 資料提供者
    Imports System.Data.OleDb					
  3. 請將下列程式碼加入 Form_Load 事件中: SQL 用戶端
    Dim PubsConn As SqlConnection = New SqlConnection & _
        ("Data Source=server;integrated security=sspi;" & _
        "initial Catalog=pubs;")
    
    Dim testCMD As SqlCommand = New SqlCommand & _
        ("TestProcedure", PubsConn)
    
    testCMD.CommandType = CommandType.StoredProcedure
    
    Dim RetValue As SqlParameter = testCMD.Parameters.Add & _
        ("RetValue", SqlDbType.Int)
    RetValue.Direction = ParameterDirection.ReturnValue
    Dim auIDIN As SqlParameter = testCMD.Parameters.Add & _
        ("@au_idIN", SqlDbType.VarChar, 11)
    auIDIN.Direction = ParameterDirection.Input
    Dim NumTitles As SqlParameter = testCMD.Parameters.Add & _
        ("@numtitlesout", SqlDbType.Int)
    NumTitles.Direction = ParameterDirection.Output
    
    auIDIN.Value = "213-46-8915"
    PubsConn.Open()
    
    Dim myReader As SqlDataReader = testCMD.ExecuteReader()
    Console.WriteLine("Book Titles for this Author:")
    Do While myReader.Read
        Console.WriteLine("{0}", myReader.GetString(2))
    Loop
    myReader.Close()
            
    Console.WriteLine("Return Value: " & (RetValue.Value))
    Console.WriteLine("Number of Records: " & (NumTitles.Value))
    					
    OLE DB 資料提供者
    Dim PubsConn As OleDbConnection = New OleDbConnection & _
        ("Provider=sqloledb;Data Source=server;" & _
        "integrated security=sspi;initial Catalog=pubs;")
    
    Dim testCMD As OleDbCommand = New OleDbCommand & _
        ("TestProcedure", PubsConn)
    
    testCMD.CommandType = CommandType.StoredProcedure
    
    Dim RetValue As OleDbParameter = testCMD.Parameters.Add & _
        ("RetValue", OleDbType.Integer)
    RetValue.Direction = ParameterDirection.ReturnValue
    Dim auIDIN As OleDbParameter = testCMD.Parameters.Add & _
        ("@au_idIN", OleDbType.VarChar, 11)
    auIDIN.Direction = ParameterDirection.Input
    Dim NumTitles As OleDbParameter = testCMD.Parameters.Add & _
        ("@numtitlesout", OleDbType.Integer)
    NumTitles.Direction = ParameterDirection.Output
    
    auIDIN.Value = "213-46-8915"
    PubsConn.Open()
    
    Dim myReader As OleDbDataReader = testCMD.ExecuteReader()
    Console.WriteLine("Book Titles for this Author:")
    Do While myReader.Read
        Console.WriteLine("{0}", myReader.GetString(2))
    Loop
    myReader.Close()
    
    Console.WriteLine("Return Value: " & (RetValue.Value))
    Console.WriteLine("Number of Records: " & (NumTitles.Value))
    					
  4. Connection 物件的連接字串修改為指向執行 SQL Server 的伺服器。
  5. 執行程式碼。請注意,DataReader 會擷取記錄,然後傳回參數值。您可以使用 DataReader 物件的 Read 方法,在傳回的記錄之間移動。

    輸出視窗會顯示兩本書的標題、傳回值 5,以及包含記錄數目 (2) 的輸出參數。 請注意,您必須關閉程式碼中的 DataReader,才能查看參數值。此外,如果 DataReader 已經關閉,您不需要在所有記錄之間移動,就可以查看傳回參數。

使用 Command 物件的 ExecuteScalar 方法

您可以使用 Command 物件的 ExecuteScalar 方法來擷取參數值。此外,ExecuteScalar 會傳回預存程序中第一筆資料列的第一個資料行。這對於如下列範例中的彙總函式特別有幫助。
  1. 在執行 SQL Server 的伺服器上建立下列預存程序:
    Create Procedure TestProcedure2
     (
       @au_idIN varchar (11)
      )
    As
    /* set nocount on */ 
    select count (T.title) 
    from authors as A join titleauthor as TA on
    A.au_id=TA.au_id
    join titles as T
    on T.title_id=TA.title_id
    where A.au_id=@au_idIN
    Return(5)
    					
  2. SystemSystem.Data 命名空間上使用 Imports 陳述式,如此您就不必在後面的程式碼中限定這些命名空間的宣告。您必須先使用 Imports 陳述式,再限定任何其他宣告。請確認您只複製已選擇之提供者的程式碼。SQL 用戶端
    Imports System.Data.SqlClient					
    OLE DB 資料提供者
    Imports System.Data.OleDb					
  3. 請將下列程式碼加入 Form_Load 事件中:SQL 用戶端
    Dim PubsConn As SqlConnection = New SqlConnection & _
        ("Data Source=server;integrated security=sspi;" & _
        "initial Catalog=pubs;")
    
    Dim testCMD As SqlCommand = New SqlCommand & _
        ("TestProcedure2", PubsConn)
    
    testCMD.CommandType = CommandType.StoredProcedure
    
    Dim RetValue As SqlParameter = testCMD.Parameters.Add & _
        ("RetValue", SqlDbType.Int)
    RetValue.Direction = ParameterDirection.ReturnValue
    Dim auIDIN As SqlParameter = testCMD.Parameters.Add & _
        ("@au_idIN", SqlDbType.VarChar, 11)
    auIDIN.Direction = ParameterDirection.Input
    
    auIDIN.Value = "213-46-8915"
    PubsConn.Open()
    
    Dim intCount As Integer = testCMD.ExecuteScalar
    Console.WriteLine(intCount)
    Console.WriteLine("Return Value: " & (RetValue.Value))
    					
    OLE DB 資料提供者
    Dim PubsConn As OleDbConnection = New OleDbConnection & _
        ("Provider=SQLOLEDB;Data Source=server;" & _
        "integrated Security=sspi;initial catalog=pubs;")
    
    Dim testCMD As OleDbCommand = New OleDbCommand & _
        ("TestProcedure2", PubsConn)
    
    testCMD.CommandType = CommandType.StoredProcedure
    
    Dim RetVal As OleDbParameter = testCMD.Parameters.Add & _
        ("RetVal", OleDbType.Integer)
    RetVal.Direction = ParameterDirection.ReturnValue
    Dim IdIn As OleDbParameter = testCMD.Parameters.Add & _
        ("@au_idIN", OleDbType.VarChar, 11)
    IdIn.Direction = ParameterDirection.Input
    
    IdIn.Value = "213-46-8915"
            
    PubsConn.Open()
    
    Dim intCount As Integer = testCMD.ExecuteScalar
    
    Console.WriteLine("Number of Rows: " & intCount)
    Console.WriteLine(RetVal.Value)
    					
  4. Connection 物件的連接字串修改為指向執行 SQL Server 的伺服器。
  5. 執行程式碼。請注意, Command 物件的 ExecuteScalar 方法會傳回參數。 ExecuteScalar 也會傳回已傳回資料列集中,第一筆資料列的第一個資料行中的值。因此,intCount 的值就是來自預存程序中 count 函式的結果。

使用 Command 物件的 ExecuteNonQuery 方法

本範例使用 ExecuteNonQuery 方法來執行查詢並傳回參數值。ExecuteNonQuery 也傳回執行查詢之後,受到影響的記錄數目。不過,ExecuteNonQuery 不會傳回來自預存程序的任何資料列或資料行。

當您使用 INSERT、UPDATE 或 DELETE 陳述式,並且只想知道變更了多少資料列時,ExecuteNonQuery 方法會特別有用。如果您在預存程序中只使用 SELECT 陳述式,就會收到 -1,這是因為沒有資料列受到查詢的影響。
  1. 在執行 SQL Server 的伺服器上建立下列預存程序:
    Create Procedure TestProcedure3
      (
    	@au_idIN varchar (11),
    	@au_fnam varchar (30)
      )
    
    As
    /* set nocount on */ 
    Update authors set au_fname = @au_fnam
    where au_id = @au_idin	return (5)
    					
  2. SystemSystem.Data 命名空間上使用 Imports 陳述式,如此您就不必在後面的程式碼中限定這些命名空間的宣告。您必須先使用 Imports 陳述式,再限定任何其他宣告。請確認您只複製已選擇之提供者的程式碼。SQL 用戶端
    Imports System.Data.SqlClient					
    OLE DB 資料提供者
    Imports System.Data.OleDb					
  3. 請將下列程式碼加入 Form_Load 事件中:SQL 用戶端
    Dim PubsConn As SqlConnection = New SqlConnection & _
        ("Data Source=server;integrated security=sspi;" & _
        "initial Catalog=pubs;")
    
    Dim testCMD As SqlCommand = New SqlCommand & _
        ("TestProcedure3", PubsConn)
    
    testCMD.CommandType = CommandType.StoredProcedure
    
    Dim RetValue As SqlParameter = testCMD.Parameters.Add & _
        ("RetValue", SqlDbType.Int)
    RetValue.Direction = ParameterDirection.ReturnValue
    Dim auIDIN As SqlParameter = testCMD.Parameters.Add & _
        ("@au_idIN", SqlDbType.VarChar, 11)
    auIDIN.Direction = ParameterDirection.Input
    Dim auFname As SqlParameter = testCMD.Parameters.Add & _
        ("@au_fnam", SqlDbType.VarChar, 30)
    auFname.Direction = ParameterDirection.Input
    
    auIDIN.Value = "213-46-8915"
    auFname.Value = "Marjorie"
    PubsConn.Open()
    
    Dim rvRows As Integer = testCMD.ExecuteNonQuery
    Console.WriteLine(rvRows)
    Console.WriteLine(RetValue.Value)
    					
    OLE DB 資料提供者
    Dim PubsConn As SqlConnection = New SqlConnection & _
        ("Data Source=server;integrated security=sspi;" & _
        "initial Catalog=pubs;")
    
    Dim testCMD As SqlCommand = New SqlCommand & _
        ("TestProcedure3", PubsConn)
    
    testCMD.CommandType = CommandType.StoredProcedure
    
    Dim RetValue As SqlParameter = testCMD.Parameters.Add & _
        ("RetValue", SqlDbType.Int)
    RetValue.Direction = ParameterDirection.ReturnValue
    Dim auIDIN As SqlParameter = testCMD.Parameters.Add & _
        ("@au_idIN", SqlDbType.VarChar, 11)
    auIDIN.Direction = ParameterDirection.Input
    Dim auFname As SqlParameter = testCMD.Parameters.Add & _
        ("@au_fnam", SqlDbType.VarChar, 30)
    auFname.Direction = ParameterDirection.Input
    
    auIDIN.Value = "213-46-8915"
    auFname.Value = "Marjorie"
    PubsConn.Open()
    
    Dim rvRows As Integer = testCMD.ExecuteNonQuery
    Console.WriteLine(rvRows)
    Console.WriteLine(RetValue.Value)
    					
  4. Connection 物件的連接字串修改為指向執行 SQL Server 的伺服器。
  5. 執行程式碼。輸出視窗會顯示受影響資料列的數目 (intRowAffect),以及傳回參數的值。

?考

如需詳細資訊,請造訪下列 MSDN 網站:
.NET Framework 類別庫 (Class Library) 簡介 (英文)
http://msdn2.microsoft.com/en-us/library/hfa3fa08(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/hfa3fa08(vs.71).aspx)

使用 DataReader 擷取資料 (英文)
http://msdn2.microsoft.com/en-us/library/haa3afyz(vs.71).aspx (http://msdn2.microsoft.com/en-us/library/haa3afyz(vs.71).aspx)
如需有關 ADO.NET 或 Visual Basic .NET 的一般相關資訊,請造訪下列 MSDN 新聞群組:
microsoft.public.dotnet.framework.adonet (http://go.microsoft.com/fwlink/?linkid=5819)

microsoft.public.dotnet.languages.vb (http://go.microsoft.com/fwlink/?linkid=5820)
如需詳細資訊,請參閱下列書籍:
Connell, John. Coding Techniques for Microsoft Visual Basic .NET (http://go.microsoft.com/fwlink/?LinkId=8395) Microsoft Press, 2001.
如需詳細資訊,請參閱下列 Microsoft Training & Certification 課程:
2389 使用 ADO.NET 進行程式設計 (英文)
http://www.microsoft.com/learning/syllabi/en-us/2389BFinal.mspx (http://www.microsoft.com/learning/syllabi/en-us/2389BFinal.mspx)

這篇文章中的資訊適用於:
  • Microsoft ADO.NET (included with the .NET Framework)
  • Microsoft ADO.NET 1.1
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual Basic .NET 2003 Standard Edition
關鍵字:?
kbhowto kbhowtomaster kbstoredproc kbsqlclient kbsystemdata KB308049
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。