许多程序员从过程式语言起手学习编程,过程式思维习惯写就的SQL代码,常常显得不那么SQL,因为SQL语言的主要特征之一是“高度非过程化”。

近日遇有一例典型:公司产品客户端程序更新后系统代码表漏添某行数据,导致某新增功能无法从界面上配置启用。后主程序组人员发来一小段T-SQL代码,供ssms执行以添加该行系统代码数据,代码大意如下:

if not exists (select 1 from 系统代码表 where 字段1 = '值1' and 字段2 = '值2')insert into 系统代码表 (字段1, 字段2, 字段3, 字段4, 字段5)values ('值1','值2','值3','值4','值5') ;

它没有语法问题,分号结尾表明程序员具备一定程度的遵循编码规范的素质,实际执行结果也符合预期,但却存在逻辑上的漏洞:if 语句判断成立的not exists()条件,当执行到 insert语句时可能已经不具备,从而导致 insert多余或重复的数据行、或因主键冲突引发执行异常。
实际执行中并未遭遇这种情形,并不能排除理论上存在的这种可能,因为数据库应用于并发场景;而 if语句的存在,表明该条 insert的执行应当受到条件限制。
系统代码表通常不会遭遇的并发写入情形,在业务字典表就会出现,而业务数据表则会时时出现。使用事务似乎是个好办法?但那是笨拙的、通常也是低效的、并且仍然是过程式思维的。不妨试着抛弃过程式思维,把SQL代码写得更加SQL一些。

指出此类问题并不是杠精行为,探讨更恰当的代码写法也不是在说“茴有几种写法”;应当使用筷子夹取宫保鸡丁,而牛排则更适合用刀叉切取。毕竟,人是人他妈生的,妖是妖它妈生的。。。_

相同的代码逻辑和执行预期,恰当的SQL写法应该是这样:

INSERT 系统代码表 (字段1, 字段2, 字段3, 字段4, 字段5 )SELECT '值1', '值2', '值3', '值4', '值5'WHERE NOT EXISTS (SELECT * FROM 系统代码表 WHERE 字段1 = '值1' AND 字段2 = '值2')

前后两段代码的区别翻译成大白话如下:
1、if not exists(…) insert 如果系统代码表中尚未存在某行数据,就 insert 那么一行;
2、insert … select … where not exists() 向系统代码表中insert 尚未存在的那么一行数据。

前者两个步骤,间隔哪怕再短暂也可能发生意外的数据变化;后者是不可分割的‘原子’操作,执行期间不可能发生意外的数据变化。
前者指示“怎么做”,属于过程式表达;后者指示“做什么”,属于非过程式表达。

不那么SQL的SQL代码(一)if not exists(...) insert相关推荐

  1. 防sql注入 php代码,完美的php防sql注入代码

    一款比较完美的php防sql注入代码,很多初学者都有被sql注入的经验吧,今天我们来分享你一款比较完整的sql防注入代码,有需要的同学可以参考一下: /************************ ...

  2. mysql执行动态批处理,使用BAT批处理执行sql语句的代码

    1.把待执行Sql保存在一个文件,这里为20110224.sql. 2.新建一个扩展名.bat的批处理文件,输入下面命令并保存后,双击.bat文件,系统会自动执行20110224.sql的语句: 复制 ...

  3. php 完美防sql注入,PHP 完美的防XSS 防SQL注入的代码

    PHP "完美"的防XSS 防SQL注入的代码 function gjj($str) { $farr = array( "/s+/", "/]*?)& ...

  4. 检测SQL注入式攻击代码

    (页面数据校验类)PageValidate.cs 基本通用. using System; using System.Text; using System.Web; using System.Web.U ...

  5. SQL经典短小代码收集

    http://topic.csdn.net/u/20080920/15/424c77bf-7610-4888-be85-9a43e70f55c6.html?4728 http://topic.csdn ...

  6. 《精通Oracle Database 12c SQL PL/SQL编程(第3版)》代码下载

    <精通Oracle Database 12c SQL & PL/SQL编程(第3版)>代码下载 清华大学出版社第五事业部 检索的时候关键词写Oracle,下面几个会有12C这个版本 ...

  7. SQL Server 在代码级别实现导入导出功能

    解决excel表数据截断问题 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\E ...

  8. PHP之SQL防注入代码,PHP防XSS 防SQL注入的代码

    360提示XSS漏洞?这个XSS漏洞很不好修复.....如果是PHP程序的话,可以用下面的代码来过滤... PHP防XSS 防SQL注入的代码 class protection{public stat ...

  9. 抽奖模块代码分享(数据库sql + java业务代码)

    抽奖模块代码分享(数据库sql + java业务代码) 最近进行的项目中,有个抽奖的需求,今天就把相关代码给大家分享一下. 一.DAO层 /*** 获取奖品列表* @param systemVersi ...

  10. SQL sever基础代码

    SQL sever基础代码,自己整理的,希望对萌新有用,不喜勿喷,谢谢!! 有不懂的欢迎在评论区留言一起讨论,此内容不是唯一解,仅作参考 --注:数据库语句基本不分大小写除表名 --1.创建数据库 - ...

最新文章

  1. 如何将Java源代码文件的编码从GBK转为UTF-8?
  2. sysfs cannot create duplicate filename问题
  3. Oracle EBS-SQL (QA-1):检查超出检验周期的检验数据.sql
  4. C# dynamic 类型用法举例
  5. 查看目标主机安装的杀毒软件
  6. sql注入攻击实例mysql_MySQL 处理SQL注入攻击
  7. visual studio 调试 定义debug常量_有趣的阅读 12个提高生产力的Visual Studio调试技巧...
  8. matlab库存点仿真教程,基于MATLABSimulink库存系统建模与仿真.doc
  9. linux内核killler,Linux内核参数overcommit_memory和OOM killer介绍
  10. Linux线程同步介绍和示例
  11. 【Java 系列笔记】语法基础 + Spring + Spring MVC + SpringBoot + 数据结构
  12. JS 继承(类式 与 原型式)
  13. java_函数的内存加载过程
  14. 【论文笔记】激光里程计网络 LO-Net:Deep Real-time Lidar Odometry2019
  15. 实验十、静态路由和直连路由引入配置
  16. 哔哩哔哩HLB站缓存合并电脑版链接:https://wwa.lanzoui.com/b016vmouf版本:1.1公告:1、支持旧版(blv)合并2、新增提取音频功能3、修复合并失败的bug
  17. 电商网站产品结构数据库设计
  18. java导出txt文件列对齐
  19. 关于程序集成线上支付模块
  20. 【Python】5行代码采集3000+上市公司信息

热门文章

  1. python如何运行js代码
  2. 问道手游服务器修改,分享一下自己架设问道手游经验和教程【图文篇】
  3. CSND博客几年没有登录了,终于找回密码来报个到!
  4. 从无线安全到内网渗透(转)
  5. 切图具体需要切什么内容_什么是切图?网页制作中的切图是什么?
  6. 【LVGL】roller选项列表问题
  7. 汽车倒车雷达系统的设计与实现(二)
  8. 推荐6款好用、免费的远程控制软件【远程管理工具】
  9. C3P0连接池的配置和使用
  10. LaTeX的字体设置