(2.3)DDL增强功能-流程化控制与动态sql
关键词:动态SQL
1.流程控制
在T-SQL中,与流程控制语句相关的关键字有8个:
BEGIN...END |
BREAK |
GOTO |
CONTINUE |
IF...ELSE |
WHILE |
RETURN |
WAITFOR
|
其实还可以加一个,那就是GO,下面我们一个一个来解释说明意思吧
(1)GO
:批处理提交语句,相当于把GO之前的所有东西都提交给系统了(平常看好像不用它也没事,但是在sqlcmd登录后dos界面使用批处理就一定要用),该销毁的销毁该回收的回收等等,演示如图
GO后面还可以加数字,会重复执行。如图:
(2)BEGIN ... END
这个其实就是逻辑块,类似于各大语言的{}
(3)while/break/continue
while (表达式) --如果表达式成立则运行begin end中的statement语句,否则略过 begin statement; end
break:直接跳出循环
continue:本次循环后续代码不执行了,直接开始下一次循环
太简单,就不演示了
(4)IF ... ELSE
IF (表达式) --如果表达式成立就执行BEGIN END中间的statement句子; BEGIN statement; END ELSE --如果IF中的表达式不成立则跳到ELSE中来,执行statement1; BEGIN statement1; END --注意:如果不写BEGIN END那么默认只有一条语句属于IF/ELSE
(5)goto
goto是个捣乱的家伙,可以随意跳到任意一个定义点,基本没什么用,一般用来跳到错误
--实现循环功能的goto 跳转
基本用法:
定义点名称:
goto 定义点名称
案例:
declare @n int set @n=1 print_point:print @n IF (@n < 3) begin set @n=@n+1 goto print_point end print 'the @n alread > 3'
结果如图:
(6)return
迅速结束任何一个批处理(batch),并且return后面的语句不会再执行了,演示如下
,发现print 5也没有执行为什么呢。记住了,批处理是以GO为结束
(7)waitfor
延迟与定点
(7.1)waitfor delay time 延迟 time(默认为秒)后继续顺序执行
(7.2)waitfor time time 定点到time的时候再顺序执行
演示如下
print 1 waitfor delay '00:00:05' --注意时间格式的写法 print 2
print 1
waitfor time '16:02:05' --注意时间格式的写法
print 2
2.动态SQL
(其他类型必须转换成字符类型才能使用动态sql)
(1)变量定义
declare @n int
分析:declare: 为关键字; @n:@为变量标识,n变量名 ;int为变量类型;
set @n = 1 ; select @n=1
分析:set为赋值关键字,用select 也可以赋值
使用的话,直接用@n即可
(2)执行动态sql
(2.1)execute,可以简写为exec
基本形式:exec sp 或 exec(字符串),演示如下
动态sql的基本演示
declare @sql varchar(1000),@t int declare @n int set @n=2 set @t=10 set @sql = 'select '+cast(@n as varchar)+' where 10 = '+cast(@t as varchar) --注意,这里其他类型必须转换成字符类型才能使用动态sql execute(@sql)--可以简写为exec
代码结果如下
execute的连接到另一个服务器操作
这就表示在链接服务器上做操作了。
(2.2)sp_executesql
其实是一个存储过程
要用exec去执行它,常用形式为: exec sp_executesql @sql ,但@sql比较为UniCode形式,演示如下
(不知道什么是Unicode的请看https://www.cnblogs.com/gered/p/9117522.html 中第5点中的字符串类型,常量字符串在前面加个N即可,如图)
sp_executesql 可以在动态SQL中做参数输入输出操作
【1】输入
declare @sql nvarchar(1000),@num int set @sql = N'select @num=1' exec sp_executesql @sql,N'@num int output',@num output --必须要在这里还要定义一次 print @num
结果:1
【2】输入输出结合
declare @sql nvarchar(1000),@num int set @sql = N'select @num=1 where @num2 = 10' exec sp_executesql @sql,N'@num int output,@num2 int',@num output,@num2=10 --如果多个参数,一一对应即可 print @num
结果:1
declare @sql nvarchar(1000);
declare @num1 int;
declare @v_id int = 2 ;
declare @table_name nvarchar(100)=N'test..test4';
set @sql = N'select @num=id from '+@table_name+N' where id=@id ';
print @v_id
exec sp_executesql @sql,N'@num int output,@id int ',@num1 output,@id=@v_id--必须要在这里还要定义一次;
print @sql
print @num1
结果:
2
select @num=id from test..test4 where id=@id
2
判断execute与sp_executesql的好坏与区别
行为相同:使用的语句或批处理在执行时才编译,编译后的内容作为执行计划运行
不同行为:execute必须要把所有东西转成字符串,sp_executesql可以入参出参。
注意事项:
(1)数据类型转换问题,在execute中必须转换成字符型,在sp_executesql中必须使用UniCode格式
(2)字符串边界问题:其实也就是单引号' 问题
举个例子,比如正常情况下
declare @str char(6)
set @str = 'a'
select 1 where @str = 'a'
换成动态sql的时候
declare @str char(6),@sql varchar(1000) set @str = 'a' set @sql = 'select 1 where '''+@str+'''=''a''' exec(@sql)
--单引号在使用其本身的时候要转移,即 ''表示为'
再举个日期的例子,直接用要报错
![](https://images2018.cnblogs.com/blog/1302413/201806/1302413-20180601174112059-1627231812.png)
正确代码如下:
--想执行的语句 select 1 where getdate() > '20180601'
declare @str datetime,@sql varchar(1000)
set @str = '20180601'
--动态sql语句
set @sql = 'select 1 where getdate() > '''+@str+''''
exec(@sql)
(3)表变量表字段问题
--想要查询test101表中的所有内容
declare @table_name char(30) set @table_name = 'test101' select * from @table_name
这样报错
--想要查询test101表中的所有内容
declare @table_name Nchar(30)
set @table_name = N'test101'
exec sp_executesql N'select * from @table_name',N'@table_name char(30)',@table_name
这样也报错
正确的打开方式如下:
declare @table_name Nchar(30),@sql nvarchar(100)
set @table_name = N'test101'
set @sql = 'select * from '+@table_name
exec (@sql)
(4) 不能再动态sql中用exec 给变量赋值,可以用sp_executesql来赋值
(2.3)使用 SET CONCAT_NULL_YIELDS_NULL OFF 来使得 'a'+null 结果为 'a' 而不是 null
当 SET CONCAT_NULL_YIELDS_NULL 为 ON 时,串联空值与字符串将产生 NULL 结果。
例如,SELECT 'abc' + NULL
将生成 NULL
。
当 SET CONCAT_NULL_YIELDS_NULL 为 OFF 时,串联空值与字符串将产生字符串本身(空值作为空字符串处理)。
例如,SELECT 'abc' + NULL
将生成 abc
。
如果未指定 SET CONCAT_NULL_YIELDS_NULL,则应用 CONCAT_NULL_YIELDS_NULL 数据库选项的设置。
备注
SET CONCAT_NULL_YIELDS_NULL 与 ALTER DATABASE 的 CONCAT_NULL_YIELDS_NULL 设置相同。
SET CONCAT_NULL_YIELDS_NULL 的设置是在执行或运行时设置的,而不是在分析时设置的。
创建或更改索引视图、计算列上的索引、筛选索引或空间索引时,SET CONCAT_NULL_YIELDS_NULL 必须为 ON。
如果 SET CONCAT_NULL_YIELDS_NULL 为 OFF,无法对包含计算列上的索引、筛选索引、空间索引或索引视图的表运行任何 CREATE、UPDATE、INSERT 和 DELETE 语句。
有关计算列的索引视图和索引需要的 SET 选项设置的详细信息,请参阅 SET Statements (Transact-SQL) 中的“使用 SET 语句时的注意事项”。
如果将 CONCAT_NULL_YIELDS_NULL 设置为 OFF,则不能出现跨服务器边界的字符串串联。
要查看此设置的当前设置,请运行以下查询。
判断是否开启
DECLARE @CONCAT_SETTING VARCHAR(3) SET @CONCAT_SETTING = 'OFF'; IF ( (4096 & @@OPTIONS) = 4096 ) SET @CONCAT_SETTING = 'ON'; SELECT @CONCAT_SETTING AS CONCAT_NULL_YIELDS_NULL;
相关文章
- [vnc] 一台显示器控制多台机器
- 如何从电脑直接控制安卓手机 监控安卓手机 安卓手机如何控制安卓手机
- SQL SERVER 2012启动失败 because upgrade step 'SSIS_hotfix_install.sql' 失败
- java.sql.SQLException: The SQL statement must not be null or empty.这个错误
- 路由控制
- 【学习总结】SQL的学习-2-sql操作
- Centos7安装部署openstack--nova计算服务(控制节点)
- Redis 优化之内存分配控制 vm.overcommit_memory
- SAP Business Application Studio的权限控制
- SQL SERVER服务器链接连接(即sql server的跨库连接)
- Atitit sql查询语法 SQL SELECT完整语法3 1.SELECT语法3 2.FROM子句5 3.WHERE子句6 下面两张表将在后面使用到7 1.比较运算符7 2.逻辑
- Atitit 读取数据库的api orm SQL Builder sql对比 目录 1.1. 提高生产效率的 ORM 和 SQL Builder1 1.2. SQL Builder 在 SQL
- Database之SQL:SQL语句操作三类(数据定义语句DDL/数据操作语句DML/数据控制语句DCL/其他基本语句、流程控制语句、批处理语句)概念及其代码实现案例之详细攻略
- Database之SQL:SQL语句操作三类(数据定义语句DDL/数据操作语句DML/数据控制语句DCL/其他基本语句、流程控制语句、批处理语句)概念及其代码实现案例之详细攻略
- Sql:成功解决将sql输出的datetime时间格式转为常规格式
- JS实现可以控制的定时器,setInterval,clearInterval
- Zigbee应用开发 协调器控制多个终端
- 010-Hadoop Hive sql语法详解5-HiveQL与SQL区别
- Go语言自学系列 | golang流程控制关键字break
- LabVIEW编程LabVIEW控制研华MIC-3680例程与相关资料
- VGA控制显示
- 游戏制作之路(5)玩家控制角色移动
- 转:企业成功变革关键:从控制到信任
- 斯坦福谷歌新研究爆火,用ChatGPT控制NPC,在虚拟世界构筑人类社会
- SQL注入 Sqli-labs-Less-21(笔记)——还是回显注入 使用union select即可 但是要注意sql括号闭合 也可以报错注入
- Linux系列 操作系统安装及服务控制(笔记)
- sql的介绍——SQL Server数据库管理系统
- 流量控制与可靠传输机制 方法 停止-等待 可靠传输 滑动窗口 性能分析 GBN 信道利用率 选择重传协议 SR 超时事件 图解 言简意赅 总结 新手上车