tbwshc

          SQLServer2008 動態SQL實踐

          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  + '

          就是錯誤的,這個想必大家都明白原因,只是寫的時候往往會忽略這個問題,這里tb提醒一下大家。

           

          另一個需要注意的是字符型的變量的判斷,要使用''來判斷是否為空而不能使用 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不是程序代碼在測試的時候會不方便一些,但是它會使程序的執行效率大大提高還是從這一點上說還是值得的。

          posted on 2012-07-19 17:30 chen11-1 閱讀(186) 評論(0)  編輯  收藏

          主站蜘蛛池模板: 名山县| 云阳县| 庄河市| 长汀县| 盐城市| 吉木乃县| 临汾市| 柘城县| 广西| 嘉定区| 铜陵市| 沂源县| 日照市| 开江县| 绥阳县| 景泰县| 阜平县| 黄山市| 藁城市| 呼图壁县| 陆良县| 景东| 阜康市| 澄迈县| 三明市| 岢岚县| 桃源县| 天镇县| 白朗县| 江都市| 桂平市| 乌兰察布市| 恩平市| 冀州市| 遂昌县| 洪江市| 桑植县| 德格县| 湟中县| 凌海市| 大丰市|