视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
SQLServer2008动态SQL实践
2020-11-09 07:40:47 责编:小采
文档


SQL Server的动态SQL功能听说了很长时间了,但是一直没有实践过。通常的项目中都是在程序中拼写SQL然后送到SQL Server中去执行,不过这样对于复杂一些或者数据量大的SQL来说不是最优,使用存储过程就是一种很好的选择方案。 一个最简单的动态SQL exec sp_exe

SQL Server的动态SQL功能听说了很长时间了,但是一直没有实践过。通常的项目中都是在程序中拼写SQL然后送到SQL Server中去执行,不过这样对于复杂一些或者数据量大的SQL来说不是最优,使用存储过程就是一种很好的选择方案。

一个最简单的动态SQL

exec sp_executesql N'select * from emp'

当然我们使用动态SQL不是来做这样简单的事情。

看看下面这个,通常我们存储过程都是这样的。

 1 CREATE PROCEDURE [dbo].[mytest]
2 @id nchar(5),
3 @s_date nchar(10),
4 @e_date nchar(10)
5 AS
6
7 declare @sql varchar(4000)
8
9 begin
10 select * from emp
11 where work_date >= ' + @s_date + ' and work_date <= ' + @e_date + '
12 end

但是如果因为业务需要传进来的参数可能为空,这个时候就需要进行判断,但是上面的代码无法完成这种需求。我们这里只是一种假设,实际的情况可能比这个复杂一些。这时候我们就需要动态SQL了。

下面这个存储过程通过使用动态SQL就很容易实现了我们程序上的这个需要。

CREATE PROCEDURE [dbo].[mytest]
@id nchar(5),
@s_date nchar(10),
@e_date nchar(10)
AS

declare @sql varchar(4000)

begin
set @sql='select * from emp '

if (@s_date <> '') and (@e_date <> '')
set @sql = @sql + ' where work_date >= ''' + @s_date + ''' and work_date <= ''' + @e_date + ''''
else
set @sql = @sql + ' where work_date is null'
end

这里要注意一个问题,还是先看例子

 1 CREATE PROCEDURE [dbo].[mytest]
2 @id nchar(5),
3 @s_date nchar(10),
4 @e_date nchar(10)
5 AS
6
7 declare @sql varchar(4000)
8
9 begin
10 set @sql='select * from emp
11 where id=''1'' and work_date is null'
12 end

注意第11行

set @sql='select * from emp
11 where id=''1'' and work_date= ''' + @s_date + ''''

如果写成

set @sql='select * from emp
11 where id='1' and work_date= ' + @s_date + '

就是错误的,这个想必大家都明白原因,只是写的时候往往会忽略这个问题,这里提醒一下大家。

另一个需要注意的是字符型的变量的判断,要使用''来判断是否为空而不能使用 is not null

if (@s_date <> '') and (@e_date <> '')
set @sql = @sql + ' where work_date >= ''' + @s_date + ''' and work_date <= ''' + @e_date + ''''
else
set @sql = @sql + ' where work_date is null'

最后一个例子,在游标中使用动态SQL,因为在游标中不能直接使用动态SQL,所以需要借助临时表来,完成动态SQL在游标中的循环执行。

 1 BEGIN TRANSACTION
2
3 --定义临时表
4 create table #tmp_table
5 (
6 id nchar(5),
7 ...
8
9 )
10
11 --执行动态SQL将记录插入到临时表中
12 insert into #tmp_table (id,...) EXECUTE sp_executesql @sql
13
14 --在游标中便利游标
15 Declare cur_tmp Cursor Scroll
16 For
17 select (id,...) from #tmp_table
18 OPEN cur_tmp
19
20 Fetch next from cur_tmp
21
22 into @id,...
23
24 while @@fetch_status=0
25 begin
26
27
28   ...
29 fetch next from cur_tmp
30 into @id,...
31
32
33 end
34 CLOSE cur_tmp
35 drop table #tmp_table
36
37 Deallocate cur_tmp
38
39
40
41 if @@error <> 0
42 begin
43
44 ROLLBACK TRANSACTION
45
46 if not (select object_id('Tempdb..#tmp_table')) is null
47 drop table #tmp_table
48
49 COMMIT TRANSACTION


动态SQL使储存过程的实现更加的灵活和方便,但是由于SQL不是程序代码在测试的时候会不方便一些,但是它会使程序的执行效率大大提高还是从这一点上说还是值得的。

下载本文
显示全文
专题