|
on conn = new SqlConnection(connectionString) )
{
SqlCommand cmd = new SqlCommand("DATRetrieveProducts", conn);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter( cmd );
DataTable dt = new DataTable("Products");
da.Fill(dt);
return dt;
}
}
按下列步骤利用SqlAdapter生成DataSet或DataTable:
创建SqlCommand对象启用存储过程,并把它与SqlConnection对象(显示的)或连接字符串(未显示)相联系。
创建一个新的SqlDataAdapter对象,并把它SqlCommand对象相联系。
创建DataTable(或者DataSet)对象。利用构造程序自变量命名DataTable.
调用SqlData Adapter对象的Fill方法,把检索的行转移到DataSet或Datatable中。
如何利用SqlDataReader检索多个行
下列代码说明了如何利用SqlDataReader方法检索多行:
using System.IO;
using System.Data;
using System.Data.SqlClient;
public SqlDataReader RetrieveRowsWithDataReader()
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=northwind");
SqlCommand cmd = new SqlCommand("DATRetrieveProducts", conn );
cmd.CommandType = CommandType.StoredProcedure;
try
{
conn.Open();
// Generate the reader. CommandBehavior.CloseConnection causes the
// the connection to be closed when the reader object is closed
return( cmd.ExecuteReader( CommandBehavior.CloseConnection ) );
}
catch
{
conn.Close();
throw;
}
}
// Display the product list using the console
private void DisplayProducts()
{
SqlDataReader reader = RetrieveRowsWithDataReader();
while (reader.Read())
{
Console.WriteLine("{0} {1} {2}",
reader.GetInt32(0).ToString(),
reader.GetString(1) );
}
reader.Close(); // Also closes the connection due to the
// CommandBehavior enum used when generating the reader
}
按下列步骤利用SqlDataReader检索多行:
创建用于执行存储的过程的SqlCommand对象,并把它与SqlConnection对象相联系。
打开链接。
通过调用SqlCommand对象的Excute Reader方法生成SqlDataReader对象。
从流中读取数据,调用SqlDataReader对象的Read方法来检索行,并利用分类的存取程序方法(如GetIut 32和Get String方法)检索列的值。
完成读取后,调用Close方法。
如何利用XmlReader检索多个行
可以利用SqlCommand对象生成XmlReader对象,它提供对XML数据的基于流的前向访问。该命令(通常是一个存储的过程)必须生成一个基于XML的结果设置,它对于SQL Server2000通常是由带有有效条款FOR XML的SELECT状态组成。下列代码段说明了这种方法:
public void RetrieveAndDisplayRowsWithXmlReader()
{
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("DATRetrieveProductsXML", conn );
cmd.CommandType = CommandType.StoredProcedure;
try
{
conn.Open();
XmlTextReader xreader = (XmlTextReader)cmd.ExecuteXmlReader();
while ( xreader.Read() )
{
if ( xreader.Name == "PRODUCTS" )
{
string strOutput = xreader.GetAttribute("ProductID");
strOutput = " ";
strOutput = xreader.GetAttribute("ProductName");
Console.WriteLine( strOutput );
}
}
xreader.Close();
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
上述代码使用了下列存储过程:
CREATE PROCEDURE DATRetrieveProductsXML
AS
SELECT * FROM PRODUCTS
FOR XML AUTO
GO
按下列步骤检索XML数据:
创建SqlCommand对象启用生成XML结果设置的过程。(比如,利用SELECT状态中的FOR XML条款)。把SqlCommand对象与一个链接相联系。
调用SqlCommand对象的ExecuteXmlReader方法,并把结果分配给前向对象XmlTextReader。当不需要任何返回数据的基于XML的验证时,这是应该使用的最快类型的XmlReader对象。
利用XmlTextReader对象的Read方法读取数据。
如何利用存储过程输出参数检索单个行
可以调用一个存储过程,它通过一种称做输出参数的方式可以在单个行中返回检索数据项。下列代码段利用存储的过程检索产品的名称和单价,该产品包含在Northwind数据库中。
void GetProductDetails( int ProductID,
out string ProductName, out decimal UnitPrice )
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=Northwind");
// Set up the command object used to execute the stored proc
SqlCommand cmd = new SqlCommand( "DATGetProductDetailsSPOutput", conn );
cmd.CommandType = CommandType.StoredProcedure;
// Establish stored proc parameters.
// @ProductID int INPUT
// @ProductName nvarchar(40) OUTPUT
// @UnitPrice money OUTPUT
// Must explicitly set the direction of output parameters
SqlParameter paramProdID =
cmd.Parameters.Add( "@ProductID", ProductID );
paramProdID.Direction = ParameterDirection.Input;
SqlParameter paramProdName =
cmd.Parameters.Add( "@ProductName", SqlDbType.VarChar, 40 );
paramProdName.Direction = ParameterDirection.Output;
SqlParameter paramUnitPrice =
cmd.Parameters.Add( "@UnitPrice", SqlDbType.Money );
paramUnitPrice.Direction = ParameterDirection.Output;
try
{
conn.Open();
// Use ExecuteNonQuery to run the command.
// Although no rows are returned any mapped output parameters
// (and potentially return values) are populated
cmd.ExecuteNonQuery( );
// Return output parameters from stored proc
ProductName = paramProdName.Value.ToString();
UnitPrice = (decimal)paramUnitPrice.Value;
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
按下列步骤利用存储的过程输出参数检索单个行:
创建一个SqlCommand对象,并把它与SqlConnection对象相联系。
通过调用SqlCommand’s Parameters集合的Add方法设置存储过程参数。缺省情况下,参数假定为输出参数,所以必须明确设置任何输出参数的方向。
注意 明确设置所有参数的方向是一次很好的练习,包括输入参数。
打开连接。
调用Sqlcommand对象的ExecuteNonQuery方法。它在输出参数(并潜在地带有一个返回值)中。
利用Value属性从合适的SqlParameter对象中检索输出参数。
关闭连接。
上述代码段启用了下列存储过程。
CREATE PROCEDURE DATGetProductDetailsSPOutput
@ProductID int,
@ProductName nvarchar(40) OUTPUT,
@UnitPrice money OUTPUT
AS
SELECT @ProductName = ProductName,
@UnitPrice = UnitPrice
FROM Products
WHERE ProductID = @ProductID
GO
如何利用SqlDataReader检索单个行
可以利用SqlDataReader对象检索单个行,以及来自返回数据流的所需栏的值。这由下列代码说明:
void GetProductDetailsUsingReader( int ProductID,
out string ProductName, out decimal UnitPrice )
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=Northwind");
// Set up the command object used to execute the stored proc
SqlCommand cmd = new SqlCommand( "DATGetProductDetailsReader", conn );
cmd.CommandType = CommandType.StoredProcedure;
// Establish stored proc parameters.
// @ProductID int INPUT
SqlParameter paramProdID = cmd.Parameters.Add( "@ProductID", ProductID );
paramProdID.Direction = ParameterDirection.Input;
try
{
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
reader.Read(); // Advance to the one and only row
// Return output parameters from returned data stream
ProductName = reader.GetString(0);
UnitPrice = reader.GetDecimal(1);
reader.Close();
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
按下列步骤返回带有SqlDataReader对象:
建立SqlCommand对象。
打开连接。
调用SqlDReader对象的ExecuteReader对象。
利用SqlDataReader对象的分类的存取程序方法检索输出参数--在这里是GetString和GetDecimal.
上述代码段启用了下列存储过程:
CREATE PROCEDURE DATGetProductDetailsReader
@ProductID int
AS
SELECT ProductName, UnitPrice FROM Products
WHERE ProductID = @ProductID
GO
如何利用ExecuteScalar单个项
ExecuteScalar方法是设计成用于返回单个值的访问。在返回多列或多行的访问事件中,ExecuteScalar只返回第一行的第一例。
下列代码说明如何查询某个产品ID的产品名称:
void GetProductNameExecuteScalar( int ProductID, out string ProductName )
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=northwind");
SqlCommand cmd = new SqlCommand("LookupProductNameScalar", conn );
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ProductID", ProductID );
try
{
conn.Open();
ProductName = (string)cmd.ExecuteScalar();
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
按下列步骤利用Execute Scalar检索单个项:
建立调用存储过程的SqlCommand对象。
打开链接。
调用ExecuteScalar方法,注意该方法返回对象类型。它包含检索的第一列的值,并且必须设计成合适的类型。
关闭链接。
上述代码启用了下列存储过程:
CREATE PROCEDURE LookupProductNameScalar
@ProductID int
AS
SELECT TOP 1 ProductName
FROM Products
WHERE ProductID = @ProductID
GO
如何利用存储过程输出或返回的参数检索单个项
利用存储过程输出或返回的参数可以查询单个值,下列代码说明了输出参数的使用:
void GetProductNameUsingSPOutput( int ProductID, out string ProductName )
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=northwind");
SqlCommand cmd = new SqlCommand("LookupProductNameSPOutput", conn );
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter paramProdID = cmd.Parameters.Add("@ProductID", ProductID );
ParamProdID.Direction = ParameterDirection.Input;
SqlParameter paramPN =
cmd.Parameters.Add("@ProductName", SqlDbType.VarChar, 40 );
paramPN.Direction = ParameterDirection.Output;
try
{
conn.Open();
cmd.ExecuteNonQuery();
ProductName = paramPN.Value.ToString();
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
按下列步骤利用存储过程的输出参数检索单个值:
创建调用存储过程的SqlCommand对象。
通过把SqlParmeters添加到SqlCommand’s Parameters集合中设置任何输入参数和单个输出参数。
打开链接。
调用SqlCommand对象的Execute NonQuery方法。
关闭链接。
利用输出SqlParameter的Value属性检索输出值。
上述代码使用了下列存储过程:
CREATE PROCEDURE LookupProductNameSPOutput
@ProductID int,
@ProductName nvarchar(40) OUTPUT
AS
SELECT @ProductName = ProductName
FROM Products
WHERE ProductID = @ProductID
GO
下列代码说明如何利用返回值确定是否存在特殊行。从编码的角度看,这与使用存储过程输出参数相类似,除了需要明确设置到ParameterDirection.ReturnValue的SqlParameter方向。
bool CheckProduct( int ProductID )
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=northwind");
SqlCommand cmd = new SqlCommand("CheckProductSP", conn );
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ProductID", ProductID );
SqlParameter paramRet =
cmd.Parameters.Add("@ProductExists", SqlDbType.Int );
paramRet.Direction = ParameterDirection.ReturnValue;
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch
{
throw;
}
finally
{
conn.Close();
}
return (int)paramRet.Value == 1;
}
按下列步骤,可以利用存储过程返回值检查是否存在特殊行:
建立调用存储过程的SqlCommand对象。
设置包含需要访问的行的主要关键字的输入参数。
设置单个返回值参数。把SqlParameter对象添加到SqlCommand’s Parameter集合中,并设置它到ParameterDireetion.ReturnValue的方面。
打开链接。
调用SqlCommand对象的ExecuteNonQuery的方法.
关闭链接。
利用返回值SqlParameter的Value属性检索返回值。
上述代码使用了下列存储过程:
CREATE PROCEDURE CheckProductSP
@ProductID int
AS
IF EXISTS( SELECT ProductID
FROM Products
WHERE ProductID = @ProductID )
return 1
ELSE
return 0
GO
如何利用SqlDataReader检索单个项。
通过调用命令对象的ExecuteReader方法,可以利用SqlDataReader对象获得单个输出值。这需要稍微多一些的代码,因为SqlDataReader Read方法必须调用,然后所需值通过读者存取程序方法得到检索。SqlDataReader对象的使用在下列代码中说明:
bool CheckProductWithReader( int ProductID )
{
SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=northwind");
SqlCommand cmd = new SqlCommand("CheckProductExistsWithCount", conn );
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ProductID", ProductID );
cmd.Parameters["@ProductID"].Direction = ParameterDirection.Input;
try
{
conn.Open();
SqlDataReader reader = cmd.ExecuteReader(
CommandBehavior.SingleResult );
reader.Read();
bool bRecordExists = reader.GetInt32(0) > 0;
reader.Close();
return bRecordExists;
}
catch
{
throw;
}
finally
{
conn.Close();
}
}
上述代码使用了下列存储过程:
CREATE PROCEDURE CheckProductExistsWithCount
@ProductID int
AS
SELECT COUNT(*) FROM Products
WHERE ProductID = @ProductID
GO
如何编码ADO.NET手工事务
下列代码说明如何利用SQL Server. NET数据供应器提供的事务支持来保护事务的支金转帐操作。该操作在位于同一数据库中的两个帐户之间转移支金。
public void TransferMoney( string toAccount, string fromAccount, decimal amount )
{
using ( SqlConnection conn = new SqlConnection(
"server=(local);Integrated Security=SSPI;database=SimpleBank" ) )
{
SqlCommand cmdCredit = new SqlCommand("Credit", conn );
cmdCredit.CommandType = CommandType.StoredProcedure;
cmdCredit.Parameters.Add( new SqlParameter("@AccountNo", toAccount) );
cmdCredit.Parameters.Add( new SqlParameter("@Amount", amount ));
SqlCommand cmdDebit = new SqlCommand("Debit", conn );
cmdDebit.CommandType = CommandType.StoredProcedure;
cmdDebit.Parameters.Add( new SqlParameter("@AccountNo", fromAccount) );
cmdDebit.Parameters.Add( new SqlParameter("@Amount", amount ));
conn.Open();
// Start a new transaction
using ( SqlTransaction trans = conn.BeginTransaction() )
{
// Associate the two command objects with the same transaction
cmdCredit.Transaction = trans;
cmdDebit.Transaction = trans;
try
{
cmdCredit.ExecuteNonQuery();
cmdDebit.ExecuteNonQuery();
// Both commands (credit and debit) were successful
trans.Commit();
}
catch( Exception ex )
{
// transaction failed
trans.Rollback();
// log exception details . . .
throw ex;
}
}
}
}
如何利用Transact-SQL执行事务
下列存储过程说明了如何在Transact-SQL过程内执行事务的支金转移操作。
CREATE PROCEDURE MoneyTransfer
@FromAccount char(20),
@ToAccount char(20),
@Amount money
AS
BEGIN TRANSACTION
-- PERFORM DEBIT OPERATION
UPDATE Accounts
SET Balance = Balance - @Amount
WHERE AccountNumber = @FromAccount
IF @@RowCount = 0
BEGIN
RAISERROR('Invalid From Account Number', 11, 1)
GOTO ABORT
END
DECLARE @Balance money
SELECT @Balance = Balance FROM ACCOUNTS
WHERE AccountNumber = @FromAccount
IF @BALANCE < 0
BEGIN
RAISERROR('Insufficient funds', 11, 1)
GOTO ABORT
END
-- PERFORM CREDIT OPERATION
UPDATE Accounts
SET Balance = Balance @Amount
WHERE AccountNumber = @ToAccount
IF @@RowCount = 0
BEGIN
RAISERROR('Invalid To Account Number', 11, 1)
GOTO ABORT
END
COMMIT TRANSACTION
RETURN 0
ABORT:
ROLLBACK TRANSACTION
GO
该存储过程使用BEGIN TRANSACTION, COMMIT TRANSACTION,和ROLLBACK TRANSACTION状态手工控制事务。
如何编码事务性的.NET类
下述例子是三种服务性的NET类,它们配置或用于自动事务。每个类都带有Transaction属性,它的值将决定是否启动新事务流或者对象是否共享即时调用程序的数据流。这些元素一起工作来执行银行支金转移。Transfer类配置有RequiresNew事务属性,而Debit和Credit类配置有Req
[5] [6] [7] [8] [9] [10]
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] 下一页
|