如何使用 sqldatareader 来检索单个行
可以使用 sqldatareader 对象来检索单个行,尤其是可以从返回的数据流中检索需要的列值。以下代码片段对此进行了说明。
void getproductdetailsusingreader( int productid,
out string productname, out decimal unitprice )
{
using( 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;
conn.open();
using( sqldatareader reader = cmd.executereader() )
{
if( reader.read() ) // advance to the one and only row
{
// return output parameters from returned data stream
productname = reader.getstring(0);
unitprice = reader.getdecimal(1);
}
}
}
}
使用 sqldatareader 对象来返回单个行
|
1. |
建立 sqlcommand 对象。 |
|
2. |
打开连接。 |
|
3. |
调用 sqldatareader 对象的 executereader 方法。 |
|
4. |
通过 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 )
{
using( 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 );
conn.open();
productname = (string)cmd.executescalar();
}
}
使用 executescalar 来检索单个项
|
1. |
建立一个 sqlcommand 对象来调用存储过程。 |
|
2. |
打开连接。 |
|
3. |
调用 executescalar 方法。注意,该方法返回一个对象类型。它包含检索到的第一列的值,并且必须转化为适当的类型。 |
|
4. |
关闭连接。 |
上述代码使用了以下存储过程:
create procedure lookupproductnamescalar @productid int as select top 1 productname from products where productid = @productid go
如何使用存储过程输出或返回参数来检索单个项
可以使用存储过程输出或返回参数来查找单个值。以下代码阐明了输出参数的用法:
void getproductnameusingspoutput( int productid, out string productname )
{
using( 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;
conn.open();
cmd.executenonquery();
productname = parampn.value.tostring();
}
}
使用存储过程输出参数来检索单个值
|
1. |
建立一个 sqlcommand 对象来调用存储过程。 |
|
2. |
通过将 sqlparameters 添加到 sqlcommand 的 parameters 集合中,设置任何输入参数和单个输出参数。 |
|
3. |
打开连接。 |
|
4. |
调用 sqlcommand 对象的 executenonquery 方法。 |
|
5. |
关闭连接。 |
|
6. |
通过使用输出 sqlparameter 的 value 属性来检索输出值。 |
上述代码使用了以下存储过程。
create procedure lookupproductnamespoutput @productid int, @productname nvarchar(40) output as select @productname = productname from products where productid = @productid go
以下代码阐明了如何使用返回值来指明是否存在特定行。从编码角度来看,这类似于使用存储过程输出参数,不同之处在于必须将 sqlparameter 方向显式设置为 parameterdirection.returnvalue。
bool checkproduct( int productid )
{
using( 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;
conn.open();
cmd.executenonquery();
}
return (int)paramret.value == 1;
}
通过使用存储过程返回值来检查是否存在特定行
|
1. |
建立一个 sqlcommand 对象来调用存储过程。 |
|
2. |
设置一个输入参数,该参数含有要访问的行的主键值。 |
|
3. |
设置单个返回值参数。将一个 sqlparameter 对象添加到 sqlcommand 的 parameters 集合中,并将其方向设置为 parameterdirection.returnvalue。 |
|
4. |
打开连接。 |
|
5. |
调用 sqlcommand 对象的 executenonquery 方法。 |
|
6. |
关闭连接。 |
|
7. |
通过使用返回值 sqlparameter 的 value 属性来检索返回值。 |
上述代码使用了以下存储过程。
create procedure checkproductsp
@productid int
as
if exists( select productid
from products
where productid = @productid )
return 1
else
return 0
go
如何使用 sqldatareader 来检索单个项
可以使用 sqldatareader 对象并通过调用命令对象的 executereader 方法来获取单个输出值。这要求编写稍微多一点的代码,因为必须调用 sqldatareader read 方法,然后通过该读取器的访问器方法之一来检索需要的值。以下代码阐明了 sqldatareader 对象的用法。
bool checkproductwithreader( int productid )
{
using( 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;
conn.open();
using( sqldatareader reader = cmd.executereader(
commandbehavior.singleresult ) )
{
if( reader.read() )
{
return (reader.getint32(0) > 0);
}
return false;
}
}
上述代码采用了以下存储过程。
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 被使用 required 进行了配置。结果,所有这三个对象在运行时都将共享同一事务。
using system;
using system.enterpriseservices;
[transaction(transactionoption.requiresnew)]
public class transfer : servicedcomponent
{
[autocomplete]
public void transfer( string toaccount,
string fromaccount, decimal amount )
{
try
{
// perform the debit operation
debit debit = new debit();
debit.debitaccount( fromaccount, amount );
// perform the credit operation
credit credit = new credit();
credit.creditaccount( toaccount, amount );
}
catch( sqlexception sqlex )
{
// handle and log exception details
// wrap and propagate the exception
throw new transferexception( "transfer failure", sqlex );
}
}
}
[transaction(transactionoption.required)]
public class credit : servicedcomponent
{
[autocomplete]
public void creditaccount( string account, decimal amount )
{
try
{
using( sqlconnection conn = new sqlconnection(
"server=(local); integrated security=sspi"; database="simplebank") )
{
sqlcommand cmd = new sqlcommand("credit", conn );
cmd.commandtype = commandtype.storedprocedure;
cmd.parameters.add( new sqlparameter("@accountno", account) );
cmd.parameters.add( new sqlparameter("@amount", amount ));
conn.open();
cmd.executenonquery();
}
}
}catch( sqlexception sqlex ){
// log exception details here
throw; // propagate exception
}
}
[transaction(transactionoption.required)]
public class debit : servicedcomponent
{
public void debitaccount( string account, decimal amount )
{
try
{
using( sqlconnection conn = new sqlconnection(
"server=(local); integrated security=sspi"; database="simplebank") )
{
sqlcommand cmd = new sqlcommand("debit", conn );
cmd.commandtype = commandtype.storedprocedure;
cmd.parameters.add( new sqlparameter("@accountno", account) );
cmd.parameters.add( new sqlparameter("@amount", amount ));
conn.open();
cmd.executenonquery();
}
}
catch (sqlexception sqlex)
{
// log exception details here
throw; // propagate exception back to caller
}
}
}
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!


