通过ado.net获取数据得三种方式
1. 使用动态sql语句
这是最之间的方式,比较简单。一般是先在客户端通过字符串操作生成sql语句,然后把sql语句发送到database engine执行
优点:比较简单,修改方便,每次改动只需要修改客户端,不用修改database。
缺点:效率不高,不能利用database来缓存执行计划,每次数据库操作都需要重新生成执行计划。存在sql 注入攻击的安全威胁,比如有如下语句
string strsql = "select * from mytable where username='" + strUserName +"'";
可以进行如下的注入,如果输入:
name';drop table mytable;--
就使得strUserName = "name';drop table mytable;--";
整个语句连接起来后就变成:
select * from mytable where username=‘name';drop table mytable;--‘
可见这是非常危险的。
2.使用带参数的sql语句
如果使用的数据库是sql server,查询语句可以这样写:
select * from product where productname = @chocolate;
然后只要在SqlCommand的Parameter collection里面加入参数的就可以了:
SqlParameter chocolateParameter = new SqlParameter("@Chocolate", SqlDbType.VarChar);
chocolateParameter.Value = "nuts";
sqlCommand.Parameters.Add(chocolateParameter);
这种方式的优点是,由于参数是强类型的,不会被SQL注入。缺点:每次执行都需要重新生成执行计划,性能不高
3. 直接调用stored procedure
调用stored procedure的方法和带参数sql语句类似,如果有参数需要输入,也是创建SqlParameter对象,然后加入到SqlCommand.Parameter集合里面。不同之处是,要指定SqlCommand的类型为StoredProcedure,如下:
sqlCommand.CommandType = CommandType.StoredProcedure;
优点:storedProcedure创建时会一次性生成一个执行计划缓存起来,以后每次调用都不用再次生成,可以提高不少性能。另外,由于参数通过sql parameter输入,可以减少Sql注入的可能性。但是用户还是可以有办法进行SQL注入攻击的,可以思考一下这个问题。:)
缺点:每次修改程序,需要同时修改客户端代码和数据库里面的storedProcedure
下面是三种方式的代码示例:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Collections;
using System.DirectoryServices;
using System.Data.SqlClient;
using System.Data;
namespace CsharpLab
{
class DefaultPageSetter
{
static void Main(string[] args)
{
Prompt("Press any key to start DB call by Plain Sql");
CallingByPlainSql();
Prompt("Press any key to start DB call by parameterized Sql");
CallingByParameterizedSql();
Prompt("Press any key to start DB call by stored procedure");
CallingByStoredProcedure();
}
private static void CallingByParameterizedSql()
{
//
// Prepare Data Operation
//
SqlConnection sqlConnection = Utilities.GetConnection();
SqlCommand sqlCommand =
new SqlCommand("select SafetyStockLevel,[Name] from Production.Product where SafetyStockLevel>@safetyStockLevel", sqlConnection);
SqlParameter safetyStockLevelParameter = new SqlParameter("@safetyStockLevel", SqlDbType.SmallInt);
safetyStockLevelParameter.Value = "799";
sqlCommand.Parameters.Add(safetyStockLevelParameter);
//
// Execute the data operation and
// retrieve the result
//
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
for (int i = 0; i < sqlDataReader.FieldCount; i++)
{
Console.Write(sqlDataReader[i]);
//
// output a separator if it's not the last column
//
if (i < sqlDataReader.FieldCount - 1)
{
Console.Write(" ");
}
}
Console.WriteLine();
Console.WriteLine();
}
}
private static void CallingByStoredProcedure()
{
//
// Prepare Data Operation
//
SqlConnection sqlConnection = Utilities.GetConnection();
string stringSql = "GetProduct";
SqlCommand sqlCommand = new SqlCommand(stringSql, sqlConnection);
sqlCommand.CommandType = CommandType.StoredProcedure;
sqlCommand.Parameters.Add("@safetyStockLevel", SqlDbType.SmallInt).Value = 799;
//
// Execute the data operation and
// retrieve the result
//
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
for (int i = 0; i < sqlDataReader.FieldCount; i++)
{
Console.Write(sqlDataReader[i]);
//
// output a separator if it's not the last column
//
if (i < sqlDataReader.FieldCount - 1)
{
Console.Write(" ");
}
}
Console.WriteLine();
Console.WriteLine();
}
}
private static void CallingByPlainSql()
{
//
// Prepare Data Operation
//
SqlConnection sqlConnection = Utilities.GetConnection();
SqlCommand sqlCommand = new SqlCommand("select SafetyStockLevel,[Name] from Production.Product", sqlConnection);
//
// Execute the data operation and
// retrieve the result
//
sqlConnection.Open();
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader();
while (sqlDataReader.Read())
{
for (int i = 0; i < sqlDataReader.FieldCount; i++)
{
Console.Write(sqlDataReader[i]);
//
// output a separator if it's not the last column
//
if (i < sqlDataReader.FieldCount - 1)
{
Console.Write(" ");
}
}
Console.WriteLine();
Console.WriteLine();
}
}
private static void Prompt(string text)
{
Console.ForegroundColor = ConsoleColor.DarkCyan;
//Console.Beep();
Console.WriteLine(text);
Console.ReadKey(true);
}
}
}