关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » SQL语言 »教您使用参数化SQL语句(1)

    教您使用参数化SQL语句(1)

    2010-09-07 10:42:00 出处:ITJS
    分享

    SQL语句的使用非常灵活,通过各种SQL语句,可以实现不同功能的操作,下面将为您介绍参数化SQL语句,供您参考,希望对您有所帮助。

    SQL注入的方法有两种:

    一是所有的SQL语句都存放在存储过程中,这样不但可以避免SQL注入,还能提高一些性能,并且存储过程可以由专门的数据库管理员(DBA)编写和集中管理,不过这种做法有时候针对相同的几个表有不同条件的查询,SQL语句可能不同,这样就会编写大量的存储过程,所以有人提出了第二种方案:参数化SQL语句。例如我们在该文中创建的表UserInfo中查找所有女性用户,那么通常情况下我们的SQL语句可能是这样:

    1 select * from UserInfo where sex=0

    在参数化SQL语句中我们将数值以参数化的形式提供,对于上面的查询,我们用参数化SQL语句表示为: 

    1 select * from UserInfo where sex=@sex

    再对代码中对这个SQL语句中的参数进行赋值,假如大家要查找UserInfo表中所有年龄大于30岁的男性用户,这个参数化SQL语句可以这么写:

    1 select * from UserInfo where sex=@sex and age>@age

    下面是执行这个查询并且将查询结果集以DataTable的方式返回的代码: 

    01 //实例化Connection对象 
    02 SqlConnection connection = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=''"); 
    03 //实例化Command对象 
    04 SqlCommand command = new SqlCommand("select * from UserInfo where sex=@sex and age>@age", connection); 
    05 //第一种添加查询参数的例子 
    06 command.Parameters.AddWithValue("@sex", true); 
    07 //第二种添加查询参数的例子 
    08 SqlParameter parameter = new SqlParameter("@age", SqlDbType.Int);//注意UserInfo表里age字段是int类型的 
    09 parameter.Value = 30; 
    10 command.Parameters.Add(parameter);//添加参数 
    11 //实例化DataAdapter 
    12 SqlDataAdapter adapter = new SqlDataAdapter(command); 
    13 DataTable data = new DataTable();

    上面的代码是访问SQL Server数据库的代码。假如本文中提到的数据分别在Access、MySQL、Oracle数据库,那么对应的参数化SQL语句及参数分别如下:

    数据库 Access MySQL Oracle
     SQL语句 select * from UserInfo

    22                 com.CommandText = string.Format(strCommand, r.Next(), r.Next());
    23                 com.ExecuteNonQuery();
    24             }
    25             com.CommandText = "truncate table test";
    26             com.ExecuteNonQuery();
    27             con.Close();
    28             Label2.Text = DateTime.Now.ToLongTimeString();
    29         }
    30         private void test2()
    31         {
    32             OracleConnection con = new OracleConnection();
    33   
    34             con.ConnectionString = "Data Source=bocodb;User Id=hljyd;Password=hljyd;Persist Security Info=True;";
    35             System.Random r = new Random((int)System.DateTime.Now.Ticks);
    36             string strCommand = "insert into test(c1,c2) values(:c1,:c2)";
    37             OracleCommand com = new OracleCommand();
    38             com.Parameters.Add(":c1", OracleType.Number);
    39             com.Parameters.Add(":c2", OracleType.Number);
    40             com.CommandText = strCommand;
    41             com.Connection = con;
    42             con.Open();
    43             Label1.Text = "传参:"+DateTime.Now.ToLongTimeString();
    44             for (int i = 0; i < 50000; i++)
    45             {
    46                 com.Parameters[":c1"].Value = r.Next();
    47                 com.Parameters[":c2"].Value = r.Next();
    48                   
    49                 com.ExecuteNonQuery();
    50             }
    51             com.Parameters.Clear();
    52             com.CommandText = "truncate table test";
    53             com.ExecuteNonQuery();
    54             con.Close();
    55             Label2.Text = DateTime.Now.ToLongTimeString();
    56         }
    57     }

    执行结果:

    SQL语句的使用非常灵活,通过各种SQL语句,可以实现不同功能的操作,下面将为您介绍参数化SQL语句,供您参考,希望对您有所帮助。

    SQL注入的方法有两种:

    一是所有的SQL语句都存放在存储过程中,这样不但可以避免SQL注入,还能提高一些性能,并且存储过程可以由专门的数据库管理员(DBA)编写和集中管理,不过这种做法有时候针对相同的几个表有不同条件的查询,SQL语句可能不同,这样就会编写大量的存储过程,所以有人提出了第二种方案:参数化SQL语句。例如我们在该文中创建的表UserInfo中查找所有女性用户,那么通常情况下我们的SQL语句可能是这样:

    1 select * from UserInfo where sex=0

    在参数化SQL语句中我们将数值以参数化的形式提供,对于上面的查询,我们用参数化SQL语句表示为: 

    1 select * from UserInfo where sex=@sex

    再对代码中对这个SQL语句中的参数进行赋值,假如大家要查找UserInfo表中所有年龄大于30岁的男性用户,这个参数化SQL语句可以这么写:

    1 select * from UserInfo where sex=@sex and age>@age

    下面是执行这个查询并且将查询结果集以DataTable的方式返回的代码: 

    01 //实例化Connection对象 
    02 SqlConnection connection = new SqlConnection("server=localhost;database=pubs;uid=sa;pwd=''"); 
    03 //实例化Command对象 
    04 SqlCommand command = new SqlCommand("select * from UserInfo where sex=@sex and age>@age", connection); 
    05 //第一种添加查询参数的例子 
    06 command.Parameters.AddWithValue("@sex", true); 
    07 //第二种添加查询参数的例子 
    08 SqlParameter parameter = new SqlParameter("@age", SqlDbType.Int);//注意UserInfo表里age字段是int类型的 
    09 parameter.Value = 30; 
    10 command.Parameters.Add(parameter);//添加参数 
    11 //实例化DataAdapter 
    12 SqlDataAdapter adapter = new SqlDataAdapter(command); 
    13 DataTable data = new DataTable();

    上面的代码是访问SQL Server数据库的代码。假如本文中提到的数据分别在Access、MySQL、Oracle数据库,那么对应的参数化SQL语句及参数分别如下:

    数据库 Access MySQL Oracle
     SQL语句 select * from UserInfo

    where sex= and age>

    select * from UserInfo

    where sex= sex and age> age

    select * from UserInfo

    where sex=:sex and age>:age

    参数 OleDbParameter MySqlParameter OracleParameter
    实例化参数 OleDbParameter p=new OleDbParameter(“ ”, OleDbType. Boolean); MySqlParameter p=new MySqlParameter(“ sex”, MySqlDbType.Bit); OracleParameter p=new OracleParameter(“:sex”, OracleType.Byte);
    赋值 p.Value=true; p.Value=1; p.Value=1;

    通过上面的实例代码我们可以看出尽管SQL语句大体相似,但是在不同数据库的特点,可能参数化SQL语句不同,例如在Access中参数化SQL语句是在参数直接以“ ”作为参数名,在SQL Server中是参数有“@”前缀,在MySQL中是参数有“ ”前缀,在Oracle中参数以“:”为前缀。

    注意:因为在Access中参数名都是“ ”,所以给参数赋值一定要按照列顺序赋值,否则就有可能执行出错。

    Command对象传参效率测试

    在.net平台,普通的insert语句有两种写法,不带参数insert into test(c1,c2) values(var1,var2)和带参数insert into test(c1,c2) values(:c1,:c2),它们的执行效率如何呢?

    做了个试验,代码如下:(数据库是oracle)

    01 public partial class WebForm1 : System.Web.UI.Page
    02     {
    03         protected void Page_Load(object sender, EventArgs e)
    04         {
    05             //test1();
    06             test2();
    07         }
    08         private void test1()
    09         {
    10             OracleConnection con = new OracleConnection();
    11             con.ConnectionString = "Data Source=oracl;User Id=xxx;Password=xxx;Persist Security Info=True;";
    12             System.Random r = new Random((int)System.DateTime.Now.Ticks);
    13             string strCommand = "insert into test(c1,c2) values({0},{1})";
    14             OracleCommand com = new OracleCommand();
    15             com.Connection = con;
    16             con.Open();
    17             DateTime dt = DateTime.Now;
    18             Label1.Text = "不传参:"+DateTime.Now.ToLongTimeString();
    19             for (int i = 0; i < 50000; i++)
    20             {
    21   
    22                 com.CommandText = string.Format(strCommand, r.Next(), r.Next());
    23                 com.ExecuteNonQuery();
    24             }
    25             com.CommandText = "truncate table test";
    26             com.ExecuteNonQuery();
    27             con.Close();
    28             Label2.Text = DateTime.Now.ToLongTimeString();
    29         }
    30         private void test2()
    31         {
    32             OracleConnection con = new OracleConnection();
    33   
    34             con.ConnectionString = "Data Source=bocodb;User Id=hljyd;Password=hljyd;Persist Security Info=True;";
    35             System.Random r = new Random((int)System.DateTime.Now.Ticks);
    36             string strCommand = "insert into test(c1,c2) values(:c1,:c2)";
    37             OracleCommand com = new OracleCommand();
    38             com.Parameters.Add(":c1", OracleType.Number);
    39             com.Parameters.Add(":c2", OracleType.Number);
    40             com.CommandText = strCommand;
    41             com.Connection = con;
    42             con.Open();
    43             Label1.Text = "传参:"+DateTime.Now.ToLongTimeString();
    44             for (int i = 0; i < 50000; i++)
    45             {
    46                 com.Parameters[":c1"].Value = r.Next();
    47                 com.Parameters[":c2"].Value = r.Next();
    48                   
    49                 com.ExecuteNonQuery();
    50             }
    51             com.Parameters.Clear();
    52             com.CommandText = "truncate table test";
    53             com.ExecuteNonQuery();
    54             con.Close();
    55             Label2.Text = DateTime.Now.ToLongTimeString();
    56         }
    57     }

    执行结果:

    10000记录:

    不传参数 5:46:19 15:46:34 15秒

    传参数:? 5:50:51 15:51:01 10秒

    50000记录:

    不传参数  16:09:03 16:10:24 81秒

    传参数::16:15:43 16:16:36 53秒

    这只是2个参数的情况,假如参数很多会不会影响更大呢?

    10000记录,7个参数:

    不传参数:17:11:01 17:11:18 17秒

    传参数:17:13:46 17:13:59 13秒

    50000记录:7个参数:

    不传参数:17:19:02 17:20:25 1分23秒

    传参数:17:15:09 17:16:10 1分1秒

    需要相差不大,但是向command对象传递参数既可以避免sql注入问题,也可以提高性能。

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    SQL汉字转换为拼音的函数

    windows 7系统无法运行Photoshop CS3的解决方法

    巧用MySQL加密函数对Web网站敏感数据进行保护

    MySQL基础知识简介

    Windows7和WinXP下如何实现不输密码自动登录系统的设置方法介绍

    windows 7系统ip地址冲突怎么办?windows 7系统IP地址冲突问题的

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。