也论该不该在项目中使用存储过程代替SQL语句

     昨天有个学生问我他的毕业设计中有个插入功能一直报错,怎么都不找不出原因,查看页面源代码后我被震惊了。她的页面中到处是sql语句,一些复杂的sql语句左拼右拼,拼得眼花缭乱,实在是惨不忍睹。我问为什么不用存储过程呢,她说学校就教了这个,没教怎么用存储过程。唉,当今大学的教育水平真是令人担忧啊。下面发表一下个人看法,如有不当之处,大家别笑掉大牙啦。

      存储过程的好处,我就不多说了,想必各位都已了然于胸。

      当然,存储过程也有不少坏处:
1,当存储过程数量越来越多的时候,在众多存储过程中找到想要修改的存储过程是一件麻烦的事.
2.如果用嵌入式SQL语句,可以在修改代码时,顺便就修改了数据库操作语句,方便

针对这两个所谓的缺点,我提出我的一些看法:
1.如果说存储过程多了,不好找,那你该检讨一下您的命名习惯是否规范是否达意,如果是多人合作的团队,大家更应该对于存储过程的命名有一致的规则,当然,不只存储过程需要这样,其他部分也都要需要这样.好的存储过程命名最好能包含操作名称(insert/update/get/list等),要操作的对象名称(表名)等,这样,即便你的存储过程再多,一样也能快速找到要改的那个。

2,对于第二种观点,我是不大同意的,在过往的例子中,我发现,将SQL语句从代码中分离出来,带来的好处远远大于坏处,而且这样更符合分层的原则,如果我们将SQL语句嵌入到代码中,当你仅需要多获取一个字段的值,或者对SQL语句本身做一些修改时,你就必须要编译,然后上传DLL,而如果你是用存储过程的话,你直接改一下存储过程就好了,而且,将二者分离,DBA写好存储过程,列好说明及使用规则,交给负责写DAL层的同学,DAL层的同学闭上眼无需了解SQL语句,也可完成他的工作,因此,从这个角度来说,很好的分隔了工作,不必要要写DAL层的同学也是SQL存储过程高手了。
3,防止注入攻击,如果不用存储过程而用嵌入式SQL,你势必要为了防止注入攻击而对输入的用户数据做更多的处理工作,例如处理一些SQL敏感字符等
4,嵌入式SQL特别是拼贴SQL语句,一向是比较容易出问题的环节,而存储过程在写的时候,就经过检查,储如漏掉符号,INSERT的字段数目与参数数目不一致的小错误,会立即被纠正
5,谁都知道存储过程是预编译的

      最常见的是,在实际运用中,为了减少DATASET数据集的大小和提高性能,通常我们只SELECT当前需要的字段,但是,随着发展,你可以需要其他字段,这时,如果用嵌入SQL,就要修改SQL语句,编译,再写上绑定该字段的表达式,但是,如果用存储过程,你只要绑定表达式,然后给存储过程中加上这个字段名就可以了.
再如,如果用STRING来拼贴SQL的INSERT语句,那很可能是这样拼
string strSql="insert into table (id,username,password,address) value ("+Id.ToString()+","+UserName...
这样拼贴,多加个字段时,一花眼,就拼贴错了
如果用存储过程,你顶多用
SqlParameter myPara=new SqlParameter("@field5",Field5);
再在存储过程里加上这个输入参数就可以了,和修改一下SQL语句就行了,SQL还会在修改过程中帮你检查语法
后者显然比前者用那么多+号与双引号拼贴出错的几率小多了

最后,以上观点仅体现个人观点,高人别石头砸我啊!

可以使用 CONCAT 函数来拼接 SQL 语句,并且使用 PREPARE 和 EXECUTE 语句来执行拼接后的 SQL 语句。 例如,假设需要在存储过程拼接一个查询语句,该查询语句需要查询一个名为 customers 的表,其包含 name 和 age 两个字段,查询年龄为 18 岁及以上的用户信息,可以使用以下存储过程: ``` DELIMITER // CREATE PROCEDURE get_customers() BEGIN DECLARE sql_query VARCHAR(255); SET sql_query = CONCAT('SELECT name, age FROM customers WHERE age >= ', 18); PREPARE stmt FROM sql_query; EXECUTE stmt; DEALLOCATE PREPARE stmt; END // DELIMITER ; ``` 在上面的存储过程,首先声明一个名为 sql_query 的变量,使用 CONCAT 函数将查询语句拼接起来,并将拼接后的 SQL 语句存储sql_query 变量。然后使用 PREPARE 语句准备执行该语句,并使用 EXECUTE 语句执行该语句。最后使用 DEALLOCATE PREPARE 释放 PREPARE 语句的内存。 需要注意的是,在拼接 SQL 语句时,应该使用参数化查询来避免 SQL 注入攻击。在参数化查询使用问号占位符代替具体的参数值,然后通过 EXECUTE 语句将参数值传递给查询语句。例如: ``` DELIMITER // CREATE PROCEDURE get_customers_by_age(IN age INT) BEGIN DECLARE sql_query VARCHAR(255); SET sql_query = CONCAT('SELECT name, age FROM customers WHERE age >= ?', age); PREPARE stmt FROM sql_query; EXECUTE stmt USING @age; DEALLOCATE PREPARE stmt; END // DELIMITER ; ``` 在上面的存储过程使用 IN 参数 age 来代替查询语句的参数值,并在 EXECUTE 语句使用 USING 子句将参数值传递给查询语句。这样可以避免 SQL 注入攻击。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍狼_2001

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值