一: 執行不帶返回參數(Input)的預存程序
1: 首先在資料庫寫個預存程序, 如建立個 addUser預存程序。
Create Proc addUser
@ID int,
@Name varchar(20),
@Sex varchar(20)
As
Insert Into Users Values( @ID, @Name,@Sex )
2:建立SqlCommand對象,並初始SqlCommand對象如:
SqlCommand cmd = new SqlCommand( );
cmd.CommandText = "addUser"; //制定調用哪個預存程序
cmd.CommandType = CommandType.StoredProcedure; // 制定Sql命令類型是預存程序, 預設的為Sql語句。
cmd.Connection = con; // 設定串連
3:向SqlCommand對象添加預存程序參數
SqlParameter param = new SqlParameter( ); //定義一個參數對象
param.ParameterName = "@ID"; //預存程序參數名稱
param.Value = txtID.Text.Trim(); // 該參數的值
cmd.Parameters.Add( param ); // SqlCommand對象添加該參數對象
param = new SqlParameter( "@Name", txtName.Text.Trim() ); // 簡寫方式
cmd.Parameters.Add( param );
4:SqlCommand對象調用執行Sql的函數。如:
cmd.ExecuteNonQuery();
二:執行帶返回參數(Output)的預存程序
1: 首先在資料庫寫個預存程序, 如建立個 queryUser預存程序。
alter Proc queryUser
@ID int,
@Suc varchar(10) output
As
select @Suc= 'false'
if exists( Select * From users where u_id = @ID )
select @Suc = 'success'
2:建立SqlCommand對象,並初始SqlCommand對象如:
SqlCommand cmd = new SqlCommand( );
cmd.CommandText = "queryUser"; //制定調用哪個預存程序
cmd.CommandType = CommandType.StoredProcedure; // 制定Sql命令類型是預存程序, 預設的為Sql語句。
cmd.Connection = con; // 設定串連
3:向SqlCommand對象添加預存程序參數
SqlParameter param1 = new SqlParameter( "@ID", txtID.Text ); // 添加輸入參數
cmd.Parameters.Add( param1 );
SqlParameter param2 = new SqlParameter(); // 添加輸出參數
param2.ParameterName = "@Suc"; // 名稱
param2.SqlDbType = SqlDbType.VarChar; // 輸出參數的Sql類型
param2.Size = 10;// 輸出參數的Sql類型大小
param2.Direction = ParameterDirection.Output; //指定該參數對象為輸出參數類型
cmd.Parameters.Add( param2 );
4:SqlCommand對象調用執行Sql的函數。如:
cmd.ExecuteNonQuery();
MessageBox.Show( param2.Value.ToString() ); // 輸出輸出參數的值
輸入參數的預存程序的樣本:
try
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "addUser";
SqlParameter param = new SqlParameter( );
param.ParameterName = "@ID";
param.Value = txtID.Text.Trim();
cmd.Parameters.Add( param );
param = new SqlParameter( "@Name", txtName.Text.Trim() );
cmd.Parameters.Add( param );
param = new SqlParameter();
param.ParameterName = "@Sex";
param.Value = txtSex.Text.Trim();
cmd.Parameters.Add( param );
//da.InsertCommand = cmd;
if ( cmd.ExecuteNonQuery() == 1 )
{
MessageBox.Show( "添加成功" );
}
else
{
MessageBox.Show("失敗");
}
}
catch( SqlException ex )
{
MessageBox.Show( ex.Message );
}
輸出參數的預存程序的樣本:
try
{
SqlCommand cmd = new SqlCommand( );
cmd.CommandText = "queryUser";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = con;
SqlParameter param1 = new SqlParameter( "@ID", txtID.Text );
cmd.Parameters.Add( param1 );
SqlParameter param2 = new SqlParameter();
param2.ParameterName = "@Suc";
param2.SqlDbType = SqlDbType.VarChar;
param2.Size = 10;
param2.Direction = ParameterDirection.Output;
cmd.Parameters.Add( param2 );
cmd.ExecuteNonQuery();
MessageBox.Show( param1.Value.ToString() );
MessageBox.Show( param2.Value.ToString() );
}
catch( SqlException ex )
{
MessageBox.Show( ex.Message );
}
在 ado.net 裡面擷取傳回值的方法為(c#):
------------------------------------------------------------
SqlConnection dbconn = new SqlConnection(connStr);
SqlCommand cmd = new SqlCommand("sp_uptmp",dbconn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tmpName = cmd.Parameters.Add("@tmpName",SqlDbType.VarChar);
SqlParameter srcPos = _cmd.Parameters.Add("@srcPos",SqlDbType.VarChar);
SqlParameter rtnval = cmd.Parameters.Add("rval",SqlDbType.Int);
tmpName.Direction = ParameterDirection.Input;
srcPos.Direction = ParameterDirection.Input;
rtnval.Direction = ParameterDirection.ReturnValue;
tmpName.Value = "";
srcPos.Value = "";
dbconn.Open();
cmd.ExecuteNonQuery();
dbconn.Close();
tmpid = (int)rtnval.Value; //此處即為傳回值
假設有預存程序如下:
---------------------------------------------
CREATE proc sp_uptmp @tmpName varchar(50),@srcPos varchar(255)
as
Begin TRAN
insert into t_template values(@tmpName,@srcPos)
COMMIT
return isnull(@@identity,0)
GO
------------------------------------------------------------
在 ado.net 裡面擷取傳回值的方法為(c#):
------------------------------------------------------------
SqlConnection dbconn = new SqlConnection(connStr);
SqlCommand cmd = new SqlCommand("sp_uptmp",dbconn);
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter tmpName = cmd.Parameters.Add("@tmpName",SqlDbType.VarChar);
SqlParameter srcPos = _cmd.Parameters.Add("@srcPos",SqlDbType.VarChar);
SqlParameter rtnval = cmd.Parameters.Add("rval",SqlDbType.Int);
tmpName.Direction = ParameterDirection.Input;
srcPos.Direction = ParameterDirection.Input;
rtnval.Direction = ParameterDirection.ReturnValue;
tmpName.Value = "";
srcPos.Value = "";
dbconn.Open();
cmd.ExecuteNonQuery();
dbconn.Close();
tmpid = (int)rtnval.Value; //此處即為傳回值
在ADO環境下,調用預存程序查詢資料時常規做法為:
1 建立Connection Command對象
2 開啟串連,給Command賦參數的名稱、資料類型、值
3 執行Command對象
4 返回給Recordset對象交給用戶端
這樣做每調用一次預存程序都要按照預存程序中的參數的資料類型建立Parameters對象
比如預存程序需要兩個參數 @ID int、@Name varchar(10)就需要
‘建立參數
cmd.Parameters.Append cmd.CreateParameter("@ID",adInteger,adParamInput,4)
cmd.Parameters.Append cmd.CreateParameter("@Name",adVarChar,adParamInput,10)
‘給參數賦值
cmd("@State") = 1
cmd("@WhereT")=”2”
每調用一個預存程序都要手工添加這個預存程序的所有參數,用自己的腦力保證參數的資料類型和預存程序中的參數的資訊的一致性。
Command.Parameters對象有一個Refresh方法,這個方法的作用時讀取當前Command對象需要的所有參數的名稱和資料類型,用這個方法就可以寫成一個調用所有預存程序的共用函數,現面這個函數完成了一個返回結果集的預存程序的通用函數。很簡單可以根據需要細化。
‘在VisualBasic6.0調試通過。
Function GetRsByPro(strConnString As String, strProName As String, arjParameter() As String)
' 返回 查詢的記錄集
' strConnString 資料連線串
' strProName 預存程序名
' arjParameter() 預存程序需要的數組
On Error GoTo errMsg
'建立ADO對象
Dim Cmd As New Command
' ASP Con = Server.CreateObject("ADODB.Connection")
Dim Con As New Connection
' ASP Set Cmd = Server.CreateObject("ADODB.Command")
Dim Rs As New Recordset
' ASP Set rs = Server.CreateObject("ADODB.Recordset")
'開啟資料庫
Con.Open strConnString
Set Cmd.ActiveConnection = Con
Cmd.Commandtype = adCmdStoredProc
Cmd.Parameters.Refresh
If UBound(arjParameter) <> Cmd.Parameters.Count Then
Debug.Print "參數個數不對"
Exit Function
End If
'給預存程序參數賦值
For i = 0 To Cmd.Parameters.Count - 1
Cmd.Parameters(i).Value = arjParameter(i)
Next
'設定Recordset對象
Rs.CursorType = 3
Rs.LockType = 3
Rs.CursorLocation = 3
Set Rs.Source = Cmd
Rs.Open
'返回結果集
Set GetRsByPro = Rs
'關閉資料來源
Con.Close
Set Con = Nothing
errMsg:
Debug.Print Err.Description
End Function
‘調用Demo
Dim Rs As New Recordset
StrConnString=””
StrProName=”pro_GetAllUser”
Dim arjParameter(1)
arjParameter(0)=”1”
arjParameter(1)=”山東”
Set Rs= GetRsByPro(strConnString, strProName, arjParameter())
用相同的方法在.NET開發環境裡也可以建立一個通用的方法調用預存程序。
在ADO.NET裡不管是OleDbCommand.Parameters對象還是SqlCommand.Parameters對象都沒有Refresh方法讀取預存程序的參數資訊,.NET在OleDbCommandBuilder類裡提供了一個DeriveParameters靜態方法可以實現相同的功能。
.NET SDK裡關於DeriveParameters的描述
“使用在 SqlCommand 中指定的預存程序的參數資訊,填充指定的 SqlCommand 對象的 Parameters 集合。”
SqlConnection Conn=new SqlConnection(cnString);
Conn.Open();
SqlCommand Comm=new SqlCommand();
Comm.Connection =conn;
Comm.CommandType =CommandType.StoredProcedure ;
Comm.CommandText =proName;
SqlCommandBuilder.DeriveParameters(comm);
//經過這個方法後SqlCommand對象的SqlParameters對象已經幫定了預存程序中的資訊了
實現執行任意一個預存程序返回一個DataSet對象的具體函數代碼
檔案名稱 :TestSqlAccess.cs
// 在vs.net調試通過
using System;
using System.Data;
using System.Xml;
using System.Data.SqlClient;
using System.Data.OleDb ;
using System.Collections;
namespace Erp
{
public sealed class TestSqlAccess
{
#region 擷取預存程序參數集合
public static SqlParameter [] getParameters(string cnString,string proName)
{
SqlConnection conn=new SqlConnection(cnString);
conn.Open();
SqlCommand comm=new SqlCommand();
comm.Connection =conn;
comm.CommandType =CommandType.StoredProcedure ;
comm.CommandText =proName;
SqlCommandBuilder.DeriveParameters(comm);
SqlParameter [] arPrm=new SqlParameter[comm.Parameters.Count];
for (int i=0;i<comm.Parameters.Count;i )
{
arPrm[i]=new SqlParameter();
arPrm[i].SqlDbType =comm.Parameters[i].SqlDbType ;
arPrm[i].ParameterName=comm.Parameters[i].ParameterName;
arPrm[i].Size =comm.Parameters[i].Size;
}
return arPrm;
}
#endregion
#region 執行Command對象返回DataSet
/////可以調用微軟提供的那個SqlHelper類..
#endregion 執行Command對象返回DataSet
使用 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. 建立一個 Visual C# .NET Windows 應用程式項目。
3. 對 System 和 System.Data 名稱空間使用 using 語句,這樣,在後面的代碼中就不需要在這些名稱空間中限定聲明了。將此代碼添加到"表單"代碼模組的頂部。請確保只複製對應於您所選的提供者的代碼。 SQL 客戶機 using System.Data.SqlClient;
OLE DB 資料提供者 using System.Data.OleDb;
4. 用以下代碼替換 private Form_Load 事件中的代碼: SQL 客戶機 SqlConnection PubsConn = new SqlConnection
("Data Source=server;integrated " +
"Security=sspi;initial catalog=pubs;");
SqlCommand testCMD = new SqlCommand
("TestProcedure", PubsConn);
testCMD.CommandType = CommandType.StoredProcedure;
SqlParameter RetVal = testCMD.Parameters.Add
("RetVal", SqlDbType.Int);
RetVal.Direction = ParameterDirection.ReturnValue;
SqlParameter IdIn = testCMD.Parameters.Add
("@au_idIN", SqlDbType.VarChar, 11);
IdIn.Direction = ParameterDirection.Input;
SqlParameter NumTitles = testCMD.Parameters.Add
("@numtitlesout", SqlDbType.VarChar, 11);
NumTitles.Direction = ParameterDirection.Output;
IdIn.Value = "213-46-8915";
PubsConn.Open();
SqlDataReader myReader = testCMD.ExecuteReader();
Console.WriteLine ("Book Titles for this Author:");
while (myReader.Read())
{
Console.WriteLine ("{0}", myReader.GetString (2));
};
myReader.Close();
Console.WriteLine("Number of Rows:" + NumTitles.Value );
Console.WriteLine("Return Value:" + RetVal.Value);
OLE DB 資料提供者 OleDbConnection PubsConn = new OleDbConnection
("Provider=SQLOLEDB;Data Source=server;" +
"integrated Security=sspi;initial catalog=pubs;");
OleDbCommand testCMD = new OleDbCommand
("TestProcedure", PubsConn);
testCMD.CommandType = CommandType.StoredProcedure;
OleDbParameter RetVal = testCMD.Parameters.Add
("RetVal", OleDbType.Integer);RetVal.Direction = ParameterDirection.ReturnValue;
OleDbParameter IdIn = testCMD.Parameters.Add
("@au_idIN", OleDbType.VarChar, 11);
IdIn.Direction = ParameterDirection.Input;
OleDbParameter NumTitles = testCMD.Parameters.Add
("@numtitlesout", OleDbType.VarChar, 11);
NumTitles.Direction = ParameterDirection.Output;
IdIn.Value = "213-46-8915";
PubsConn.Open();
OleDbDataReader myReader = testCMD.ExecuteReader();
Console.WriteLine ("Book Titles for this Author:");
while (myReader.Read())
{
Console.WriteLine ("{0}", myReader.GetString (2));
};
myReader.Close();
Console.WriteLine("Number of Rows:" + NumTitles.Value );
Console.WriteLine("Return Value:" + RetVal.Value);
5. 修改 Connection 對象的連接字串,以便指向運行 SQL Server 的電腦。
6. 運行此代碼。注意,DataReader 檢索記錄並返回參數值。您可以使用 DataReader 對象的 Read 方法遍曆返回的記錄。
輸出視窗顯示兩本書的標題、傳回值 5 和輸出參數,其中包含記錄的數目 (2)。注意,您必須關閉代碼中的 DataReader 才能看到參數值。另請注意,如果關閉了 DataReader,則不必為了查看返回參數而遍曆所有記錄。