不那么SQL的SQL代码(一)if not exists(...) insert
许多程序员从过程式语言起手学习编程,过程式思维习惯写就的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相关推荐
- 防sql注入 php代码,完美的php防sql注入代码
一款比较完美的php防sql注入代码,很多初学者都有被sql注入的经验吧,今天我们来分享你一款比较完整的sql防注入代码,有需要的同学可以参考一下: /************************ ...
- mysql执行动态批处理,使用BAT批处理执行sql语句的代码
1.把待执行Sql保存在一个文件,这里为20110224.sql. 2.新建一个扩展名.bat的批处理文件,输入下面命令并保存后,双击.bat文件,系统会自动执行20110224.sql的语句: 复制 ...
- php 完美防sql注入,PHP 完美的防XSS 防SQL注入的代码
PHP "完美"的防XSS 防SQL注入的代码 function gjj($str) { $farr = array( "/s+/", "/]*?)& ...
- 检测SQL注入式攻击代码
(页面数据校验类)PageValidate.cs 基本通用. using System; using System.Text; using System.Web; using System.Web.U ...
- SQL经典短小代码收集
http://topic.csdn.net/u/20080920/15/424c77bf-7610-4888-be85-9a43e70f55c6.html?4728 http://topic.csdn ...
- 《精通Oracle Database 12c SQL PL/SQL编程(第3版)》代码下载
<精通Oracle Database 12c SQL & PL/SQL编程(第3版)>代码下载 清华大学出版社第五事业部 检索的时候关键词写Oracle,下面几个会有12C这个版本 ...
- SQL Server 在代码级别实现导入导出功能
解决excel表数据截断问题 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\E ...
- PHP之SQL防注入代码,PHP防XSS 防SQL注入的代码
360提示XSS漏洞?这个XSS漏洞很不好修复.....如果是PHP程序的话,可以用下面的代码来过滤... PHP防XSS 防SQL注入的代码 class protection{public stat ...
- 抽奖模块代码分享(数据库sql + java业务代码)
抽奖模块代码分享(数据库sql + java业务代码) 最近进行的项目中,有个抽奖的需求,今天就把相关代码给大家分享一下. 一.DAO层 /*** 获取奖品列表* @param systemVersi ...
- SQL sever基础代码
SQL sever基础代码,自己整理的,希望对萌新有用,不喜勿喷,谢谢!! 有不懂的欢迎在评论区留言一起讨论,此内容不是唯一解,仅作参考 --注:数据库语句基本不分大小写除表名 --1.创建数据库 - ...
最新文章
- 如何将Java源代码文件的编码从GBK转为UTF-8?
- sysfs cannot create duplicate filename问题
- Oracle EBS-SQL (QA-1):检查超出检验周期的检验数据.sql
- C# dynamic 类型用法举例
- 查看目标主机安装的杀毒软件
- sql注入攻击实例mysql_MySQL 处理SQL注入攻击
- visual studio 调试 定义debug常量_有趣的阅读 12个提高生产力的Visual Studio调试技巧...
- matlab库存点仿真教程,基于MATLABSimulink库存系统建模与仿真.doc
- linux内核killler,Linux内核参数overcommit_memory和OOM killer介绍
- Linux线程同步介绍和示例
- 【Java 系列笔记】语法基础 + Spring + Spring MVC + SpringBoot + 数据结构
- JS 继承(类式 与 原型式)
- java_函数的内存加载过程
- 【论文笔记】激光里程计网络 LO-Net:Deep Real-time Lidar Odometry2019
- 实验十、静态路由和直连路由引入配置
- 哔哩哔哩HLB站缓存合并电脑版链接:https://wwa.lanzoui.com/b016vmouf版本:1.1公告:1、支持旧版(blv)合并2、新增提取音频功能3、修复合并失败的bug
- 电商网站产品结构数据库设计
- java导出txt文件列对齐
- 关于程序集成线上支付模块
- 【Python】5行代码采集3000+上市公司信息