ADO.NET笔记——调用存储过程
相关知识:
- 在ADO.NET访问SQL Server时,鼓励使用存储过程取代常规的SQL语句。
- 存储过程有下列优点:
- 存储过程中的SQL语句将会经过预先的解析和编译,然后存放在数据库服务器上行。调用的时候不必在此解析语法和编译,因此效率比采用常规SQL语句高
- 带参数的存储过程在一定程度上可以降低SQL注入攻击的风险
- 存储过程便于在数据库服务器上统一管理,减少了程序员维护SQL代码的工作量
- 存储过程有利于重用某些数据库的访问逻辑
代码示例:
- 在数据库中创建存储过程(沿用SQLInjection案例描述的数据库。请确保Account表中有若干行数据)
- 不带参数的存储过程:forAccountGetAll
CREATE PROCEDURE forAccountGetAll AS SELECT AccountID, AccountName, Password FROM Account
- 带输入参数的存储过程:forAccountInsert
CREATE PROCEDURE forAccountInsert (@AccountID int, @AccountName nvarchar(50), @Password nvarchar(50) )AS INSERT INTO Account(AccountID, AccountName, password) VALUES(@AccountID, @AccountName, @password)
- 带输入和输出从参数的存储过程:根据用户名和密码,找到匹配的AccountID作为输出参数:forAccountLogin
CREATE PROCEDURE forAccountLogin (@AccountName nvarchar(50), @Password nvarchar(50), @AccountID int output )AS SELECT @AccountID=AccountID FROM Account WHERE AccountName=@AccountName AND password=@password
- 代码
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Data; 7 using System.Data.SqlClient; 8 9 namespace ConsoleApplication12 10 { 11 class Program 12 { 13 static string strConn = @"server=Joe-PC;database=AccountDBforSQLInjection;uid=sa;pwd=root"; 14 static SqlConnection conn = new SqlConnection(strConn); 15 static void Main(string[] args) 16 { 17 //调用不带参数的存储过程 18 //CallProcedureGetAll(); 19 //调用带输入参数的存储过程 20 //CallProcedureInsert(); 21 //调用带输入和输出参数的存储过程 22 //CallProcedureLogin(); 23 } 24 25 static void CallProcedureGetAll() 26 { 27 string sql = "forAccountGetAll";//存储过程名字 28 29 SqlDataAdapter da = new SqlDataAdapter(sql, conn); 30 da.SelectCommand.CommandType = CommandType.StoredProcedure;//指定调用存储过程(默认是SQL文本) 31 32 DataSet ds = new DataSet(); 33 da.Fill(ds, "AccountGetAll"); 34 35 DataTable dt = ds.Tables["AccountGetAll"]; 36 DataView dv = new DataView(dt); 37 38 dv.Sort = "AccountID ASC"; 39 40 Console.WriteLine("调用存储过程 forAccountGetAll:"); 41 42 foreach (DataRowView drv in dv) 43 { 44 Console.WriteLine("{0}:{1},{2}", drv["AccountID"], drv["AccountName"], drv["password"]); 45 } 46 } 47 48 static void CallProcedureInsert() 49 { 50 string sql = "forAccountInsert"; 51 SqlCommand cmd = new SqlCommand(sql, conn); 52 53 cmd.CommandType = CommandType.StoredProcedure; 54 //设置参数值,并添加到Command对象的参数集合中 55 cmd.Parameters.AddWithValue("@AccountID", 100); 56 cmd.Parameters.AddWithValue("@AccountName", "new"); 57 cmd.Parameters.AddWithValue("@password", "123456"); 58 59 conn.Open(); 60 cmd.ExecuteNonQuery(); 61 conn.Close(); 62 } 63 64 static void CallProcedureLogin() 65 { 66 string sql = "forAccountLogin"; 67 SqlCommand cmd = new SqlCommand(sql, conn); 68 69 cmd.CommandType = CommandType.StoredProcedure; 70 //设置输入参数值 71 cmd.Parameters.AddWithValue("@AccountName", "Joe"); 72 cmd.Parameters.AddWithValue("@password", "123456"); 73 //准备输出参数 74 SqlParameter param = new SqlParameter("@AccountID", SqlDbType.Int); 75 param.Direction = ParameterDirection.Output;//指定是输出参数 76 77 cmd.Parameters.Add(param); // 将输出参数添加到Command对象的参数集合中 78 79 conn.Open(); 80 cmd.ExecuteNonQuery(); 81 //如果没有满足条件的用户名和密码,那么输出参数@AccountID的值将为DBNull.Value 82 if (param.Value == DBNull.Value) 83 { 84 Console.WriteLine("failed"); 85 } 86 else 87 { 88 Console.WriteLine("Done"); 89 } 90 conn.Close(); 91 } 92 } 93 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。