<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 3, 文章 - 152, 評論 - 17, 引用 - 0
    數據加載中……

    我的第一個存儲過程(轉)

    存儲過程學習記錄1
    我的第一個存儲過程

    該存儲過程的功能是去完成在多個無關系數據表中執行聯合查詢和計算,最后生成一個統計表。

    這個存儲過程中包括了:參數傳遞,存儲過程間相互調用并返回結果集到臨時表中,使用sp_executesql執行動態生成的Sql語句,臨時表的創建以及使用

    ==============================================================

    CREATE procedure sp_MakeCond
     @FdName nvarchar(20),
     @FdRecord nvarchar(250),
     @CXZT int,
     @GSBM nvarchar(10),
     @Cond nvarchar(250) output
    as

     /*
     功能:
      根據@CXZT的狀態,對于字段@FdName進行內容@FdRecord的匹配。
      當@FdRecord中有內容的時候,進行匹配
      當@GSBM中有內容的時候,添加GSBM的條件
     輸入:
      @FdName 字段名稱
      @FdRecord    字段內容
      @GSBM 
      @CXZT      查詢狀態 0-表示精確,1-表示模糊,2-表示智能
          該狀態僅對KHMC起作用
     輸出:
      @Cond   條件語句 例如: 
        輸入   dwmc,'上海',1,'RRL'
        輸出 dwmc like '上海%' and gsbm='RRL' 
     */
     
     /*
     創建人: 
     創建日期:
     --對于改存儲過程的版本更新記錄在這個地方

     */
     declare @HaveFdRecord as int

     Set @HaveFdRecord = 0
     Set @Cond = ''

     /* 添加FdRecord */
     if len(rtrim(ltrim(@FdRecord)))>0
     begin
     select @Cond=
      case @CXZT
       when 0 then
        @Cond + @FdName + N'=''' + @FdRecord + ''''
       when 1 then
        @Cond + @FdName + N' like ''' + @FdRecord + '%'''
       when 2 then
        @Cond + @FdName + N' like ''%' + @FdRecord + '%'''
       end
      set @HaveFdRecord = 1
     end

     /* 添加GSBM */
     if len(rtrim(ltrim(@GSBM)))>0
     begin
      if @HaveFdRecord=1
      begin
       Set @Cond = @Cond + ' and '
      end
      set @Cond = @Cond + ' gsbm=''' + @GSBM + ''''
     end
    GO


    ==============================================================

    CREATE Procedure sp_Math_KHYE
     @KHMC nvarchar(250),
     @JZRQ datetime,
     @CXZT int,
     @GSBM nvarchar(10)
    as
     /*
     功能:
     輸入:
      @KHMC  客戶名稱
      @CXZT 查詢狀態 0-表示精確,1-表示模糊,2-表示智能
        該狀態僅對KHMC起作用
      @JZRQ  截至日期
      @GSBM 
     輸出:
      @ReturnKHYE  根據條件計算出來的客戶余額
     說明:在調用該過程前,需按照如下語句定義一個命名為#KHYEReturn的臨時表
     Create Table #KHYEReturn
      (dwmc nvarchar(250),khye decimal(15,6))
     在使用完畢#KHYEReturn后,應該立刻使用下列語句釋放該臨時表
     delete from #KHYEReturn
     drop Table #KHYEReturn
     */

     /*
     實現方法:
      
     */

     /*
     創建人: 
     創建日期:

     --對于改存儲過程的版本更新記錄在這個地方

     */
     
     Declare @SqlString nvarchar(1000)
     Declare @Cond nvarchar(250)

    -- 制作查詢條件,存入@Cond 
    EXECUTE sp_MakeCond 'dwmc',@KHMC,@CXZT,@GSBM,@Cond output
     
     /*  */
     set @SqlString = 'select dwmc,sum(xhsl*hsj) as xsje from xsdda where xsrq<=@vJZRQ and ' + @Cond
     set @SqlString = @SqlString + ' group by dwmc'

     Create table #sp_Math_KHYE_XSJE(dwmc nvarchar(250),xsje decimal(15,6))
     
     Declare @ParmDefinition nvarchar(100)
     set @ParmDefinition = '@vKHMC nvarchar(250),@vJZRQ datetime'

    -- 這個地方就是調用sp_executesql來執行動態SqlString并將結果返回到一張臨時表里面

    -- 在這里,曾經試圖將結果返回到游標中間,但是沒有成功。
    -- 根據資料 insert 和 exec 是不能夠嵌套執行的,不過在這個地方比較奇怪,這兩個可以嵌套執行。
    -- 需要注意的地方:@ParmDefnition是用來定義在sp_executesql中間要使用的變量的。
    -- 曾經試驗這個地方直接傳一個字符串,不使用變量傳遞,結果報錯。不知道有沒有其它的人成功過
    -- 在@ParmDefinition后面就要傳遞一個變量列表,按照我的理解,
    -- 就是在這個地方給sp_executesql過程中要使用的變量(也就是Sql語句的變量)賦值

     insert into #sp_Math_KHYE_XSJE EXECUTE sp_executesql  @SqlString,   
          @ParmDefinition,
          @vKHMC=@KHMC,
           @vJZRQ=@JZRQ

     /*  */
     set @SqlString = ''
     set @SqlString = 'select dwmc,sum(bcsk+ysk) as fkje from xhskdda where skrq<=@vJZRQ and ' + @Cond
     set @SqlString = @SqlString + ' group by dwmc'

     Create table #sp_Math_KHYE_FKJE(dwmc nvarchar(250),fkje decimal(15,6))
     
     set @ParmDefinition=''
     set @ParmDefinition = '@vKHMC nvarchar(250),@vJZRQ datetime'
     insert into #sp_Math_KHYE_FKJE EXECUTE sp_executesql  @SqlString,
          @ParmDefinition,
          @vKHMC=@KHMC,
           @vJZRQ=@JZRQ
     
     Create Table #sp_Math_KHYE_Result(
      dwmc nvarchar(250),khye decimal(15,6))

    -- 比較簡單的Sql語句了,左聯右聯,BT的需求,只能用BT的寫法

     insert into #sp_Math_KHYE_Result
     select distinct T1.dwmc as dwmc,(T1.fkje-T1.xsje) as khye from
     (
     select
      #sp_Math_KHYE_XSJE.dwmc as dwmc,
      isnull(#sp_Math_KHYE_XSJE.xsje,0) as xsje,
      isnull(#sp_Math_KHYE_FKJE.fkje,0) as fkje
     from #sp_Math_KHYE_XSJE,#sp_Math_KHYE_FKJE
     where #sp_Math_KHYE_XSJE.dwmc*=#sp_Math_KHYE_FKJE.dwmc
     union
     select
      #sp_Math_KHYE_XSJE.dwmc as dwmc,
      isnull(#sp_Math_KHYE_XSJE.xsje,0) as xsje,
      isnull(#sp_Math_KHYE_FKJE.fkje,0) as fkje
     from #sp_Math_KHYE_XSJE,#sp_Math_KHYE_FKJE
     where #sp_Math_KHYE_FKJE.dwmc*=#sp_Math_KHYE_XSJE.dwmc
     ) as T1

     insert into #KHYEReturn select * from #sp_Math_KHYE_Result
    GO


    ==================================================================


    CREATE Procedure sp_KHYEXYTJ
     @StartDate datetime,
     @EndDate datetime,
     @KHMC nvarchar(250),
     @CXZT int,
     @GSBM nvarchar(100)
    as
     /*
     功能:
     輸入:
      @StartDate 開始日期
      @EndDate    截至日期
      @KHMC 客戶名稱
      @CXZT      查詢狀態 0-表示精確,1-表示模糊,2-表示智能
          該狀態僅對KHMC起作用
      @GSBM 
     輸出:
      
      表結構:
       dwmc ncye  ssye  bqxs  qmye  khxye  cxye
     */
     
     /*
     創建人: 
     創建日期:

     --對于改存儲過程的版本更新記錄在這個地方

     */

      -- 這個地方求了一堆亂七八糟的數據,是需要用來輸出的。

     -- 求得表#sp_KHYEXYTJ_QMKHYE
     Create Table #sp_KHYEXYTJ_QMKHYE
      (dwmc nvarchar(250),QMkhye decimal(15,6))
     Create Table #KHYEReturn
      (dwmc nvarchar(250),khye decimal(15,6))
     execute sp_Math_KHYE @KHMC,@EndDate,@CXZT,@GSBM
     insert into #sp_KHYEXYTJ_QMKHYE(dwmc,QMKHYE) select * from #KHYEReturn
     delete from #KHYEReturn

     -- 求得表#sp_KHYEXYTJ_QMKHYE
     Declare @NowDate datetime
     set @NowDate = GetDate()
     Create Table #sp_KHYEXYTJ_KHYE
      (dwmc nvarchar(250),khye decimal(15,6))
     execute sp_Math_KHYE @KHMC,@NowDate,@CXZT,@GSBM
     insert into #sp_KHYEXYTJ_KHYE select * from #KHYEReturn
     delete from #KHYEReturn

     -- 求得表#sp_KHYEXYTJ_NCYE
     Create Table #sp_KHYEXYTJ_NCYE
      (dwmc nvarchar(250),ncye decimal(15,6))
     Set @NowDate=cast(str(year(GetDate()))+'-01-01 00:00:00' as datetime)
     execute sp_Math_KHYE @KHMC,@NowDate,@CXZT,@GSBM
     insert into #sp_KHYEXYTJ_NCYE select * from #KHYEReturn
     delete from #KHYEReturn
     drop table #KHYEReturn

     --
     Declare @SqlString nvarchar(500)
     Declare @Cond nvarchar(100)

    -- 這里也是求查詢條件的地方
     EXECUTE sp_MakeCond 'dwmc',@KHMC,@CXZT,@GSBM,@Cond output

     set @SqlString = 'select dwmc,sum(xhsl*hsj) as xsje from xsdda where xsrq<=@vEndDate and xsrq>=@vStartDate and ' + @Cond
     set @SqlString = @SqlString + ' group by dwmc'

     Create table #sp_KHYEXYTJ_XSJE(dwmc nvarchar(250),xsje decimal(15,6))
     
     Declare @ParmDefinition nvarchar(100)
     set @ParmDefinition = '@vKHMC nvarchar(250),@vEndDate datetime,@vStartDate datetime'
     insert into #sp_KHYEXYTJ_XSJE EXECUTE sp_executesql  @SqlString,
          @ParmDefinition,
          @vKHMC=@KHMC,
           @vEndDate=@EndDate,
          @vStartDate=@StartDate

     -- 制作輸出表
     Create Table #sp_KHYEXYTJ_ReslutTable
      (dwmc nvarchar(250),
      ncye decimal(15,6),
      ssye decimal(15,6),
      bqxs decimal(15,6),
      qmye decimal(15,6),
      khxye decimal(15,6),
      cxye decimal(15,6))

      -- 下面就是一堆亂七八糟的東西了。本來是將數據放到游標中去,然后對游標進行循環處理
      --  不過好像速度卻很慢,一共是3張數據表,三章表數據分別為1k,4k,2W,
      -- 用游標處理,最終返回統計表600條數據用了27秒,一個比較讓人發傻的時間
      -- 可能是我寫的不好吧,但是這個時間也確實太長了
      -- 所以,就又換成按照臨時表來處理,分別將各個需要統計的數據分開統計,
      -- 然后放入到不同的臨時表里面,最后再將所有的數據根據dwmc這個字段進行關聯,一起輸出。
      -- 最終查詢結果,同樣數據量,用時2秒鐘。
      -- 對于這個時間來說,我還是比較滿意的。因為算的數據比較多了,而且和前面用游標用了27s
      -- 根本就不是一個等量級。不管好壞,先可以拿出來見人了。

     -- 寫入輸出表,并生成統計列表
     insert into #sp_KHYEXYTJ_ReslutTable(dwmc,bqxs)
      select dwmc,xsje from #sp_KHYEXYTJ_XSJE

     -- 寫入輸出表
     update #sp_KHYEXYTJ_ReslutTable
      set #sp_KHYEXYTJ_ReslutTable.ssye = #sp_KHYEXYTJ_KHYE.khye
      from #sp_KHYEXYTJ_KHYE
      where #sp_KHYEXYTJ_ReslutTable.dwmc = #sp_KHYEXYTJ_KHYE.dwmc

     --寫入輸出表
     update #sp_KHYEXYTJ_ReslutTable
      set #sp_KHYEXYTJ_ReslutTable.qmye = #sp_KHYEXYTJ_QMKHYE.QMkhye
      from #sp_KHYEXYTJ_QMKHYE
      where #sp_KHYEXYTJ_ReslutTable.dwmc = #sp_KHYEXYTJ_QMKHYE.dwmc

     -- 寫入輸出表
     update #sp_KHYEXYTJ_ReslutTable
      set #sp_KHYEXYTJ_ReslutTable.ncye = #sp_KHYEXYTJ_NCYE.ncye
      from #sp_KHYEXYTJ_NCYE
      where #sp_KHYEXYTJ_ReslutTable.dwmc = #sp_KHYEXYTJ_NCYE.dwmc

     -- 計算
     update #sp_KHYEXYTJ_ReslutTable
      set #sp_KHYEXYTJ_ReslutTable.khxye = isnull(xhkhda.khxye,0),
           #sp_KHYEXYTJ_ReslutTable.cxye = abs(#sp_KHYEXYTJ_ReslutTable.ssye)-isnull(xhkhda.khxye,0)
      from xhkhda
      where #sp_KHYEXYTJ_ReslutTable.dwmc = xhkhda.dwmc

     --最終輸出結果了,因為都是算得金額了,為了減小誤差,在計算的時候
     -- 全部使用6位小數,在輸出的時候,取了兩位小數來輸出

     -- 輸入表
     select
      rtrim(ltrim(dwmc)) as dwmc,
      cast(round(isnull(ncye,0),2) as decimal(15,2)) as ncye,
      cast(round(isnull(ssye,0),2) as decimal(15,2)) as ssye,
      cast(round(isnull(bqxs,0),2) as decimal(15,2)) as bqxs,
      cast(round(isnull(qmye,0),2) as decimal(15,2)) as qmye,
      cast(round(isnull(khxye,0),2) as decimal(15,2)) as khxye,
      cast(round(isnull(
      case
       when cxye<= 0 then 0
       when cxye>0 then cxye
      end,0),2) as decimal(15,2)) as cxye

     from #sp_KHYEXYTJ_ReslutTable
    GO

    這三個存儲過程寫的比較亂啦,畢竟是我的第一個存儲過程嘛。可以諒解的。不過以后就不能寫這么亂的存儲過程了,否則不可饒恕。

    在這三個存儲過程中有一些地方寫的還是不盡人意,比方說,存儲過程A調用存儲過程B,而存儲過程B需要返回一個結果集供A使用。雖然用了一個臨時表來作為存儲用,可是總想象寫OO一樣,把臨時表或者結果集象對象一樣返回出去。記得在寫這個地方的前一天偶然看了資料,可以把結果集放到游標中output出去。不過寫的時候忘記了在什么地方看到的了,又犯了懶,所以干脆就直接使用一個臨時表,反正游標返回出來后,也是要放到臨時表里面去的嘛。

    posted on 2005-02-28 21:06 閱讀(225) 評論(0)  編輯  收藏 所屬分類: 數據庫相關

    主站蜘蛛池模板: 噜噜综合亚洲AV中文无码| 你懂的免费在线观看| 日韩免费无码视频一区二区三区| 亚洲色欲久久久久综合网| 日本亚洲成高清一区二区三区| 亚洲国产亚洲片在线观看播放| 16女性下面扒开无遮挡免费| 免费羞羞视频网站| 亚洲永久无码3D动漫一区| 最近更新免费中文字幕大全| 久久久影院亚洲精品| 99视频有精品视频免费观看| 亚洲激情电影在线| 两个人日本免费完整版在线观看1 两个人的视频www免费 | 久久久久亚洲国产| 永久久久免费浮力影院| 日本激情猛烈在线看免费观看| 国色精品卡一卡2卡3卡4卡免费| 亚洲国产婷婷六月丁香| 女bbbbxxxx另类亚洲| 好先生在线观看免费播放 | 久久亚洲春色中文字幕久久久| 亚洲电影在线免费观看| 亚洲av乱码一区二区三区按摩| 亚洲天堂免费在线视频| 久久免费福利视频| 亚洲熟妇av一区二区三区漫画| 毛片免费在线观看| 国产成人毛片亚洲精品| 久久久免费精品re6| 亚洲av永久无码精品网址| 亚洲中文字幕无码爆乳AV| 亚州免费一级毛片| 免费在线人人电影网| 老司机亚洲精品影院无码| 日韩电影免费在线观看视频| 亚洲欧洲无卡二区视頻| 中国在线观看免费国语版| 亚洲国产成人综合| 亚洲成av人片在线观看天堂无码| 蜜桃传媒一区二区亚洲AV |