1. 程式人生 > >oracle 動態sql引數帶date型別無法執行的問題

oracle 動態sql引數帶date型別無法執行的問題

      之前在寫儲存過程時,我有一個目的是通過開始時間和結束時間來建立一個檢視,於是我這麼寫了一個過程:

 procedure prc_CreateViewOBookTcert(p_startdate in date,        --統計的開始日期
                                      p_enddate in date)          --統計的結束日期
   is
   v_sql varchar2(2000);
   begin
     v_sql :=
     'create or replace view v_obook_tcert as
       select * from(
           select
           nvl(t11.region,nvl(t22.region,t33.region)) region,
           nvl(t11.site,0) site,
           nvl(t22.useland,0) useland,
           nvl(t33.project,0) project,
           nvl((nvl(t11.site,0)+nvl(t22.useland,0)+nvl(t33.project,0)),0) subtotal--統計某一區域選址、用地、工程的和
          from
            (select t1.專案所在區 region,count(t1.專案所在區) site--統計選址
             from ts_project t1
             where t1.ref_business_id=1 and t1.發證日期 between '||p_startdate||' and '||p_enddate||'
             group by t1.專案所在區) t11
          full join
            (select t2.專案所在區 region,count(t2.專案所在區) useland--統計用地
             from ts_project t2
             where t2.ref_business_id=3 and t2.發證日期 between '||p_startdate||' and '||p_enddate||'
             group by t2.專案所在區) t22
             on t11.region=t22.region
          full join
            (select t3.專案所在區 region,count(t3.專案所在區) project--統計工程
             from ts_project t3
             where t3.ref_business_id in(5,9,11) and t3.發證日期 between '||p_startdate||' and '||p_enddate||'
             group by t3.專案所在區) t33
          on t22.region=t33.region)';
      execute immediate v_sql;
   end prc_CreateViewOBookTcert;
     黃色區域是關鍵地方,這個過程語法是沒有問題的,把引數變數值換成實際值也是有效的。可是就是在呼叫的時候無效。也就是說只要把實際值用變數來代替就無效了。其實這種情況經常會出現,在 集合查詢的時候也會出現這樣的錯誤。今天突然想是不是空格什麼的沒注意,於是我改成了這樣的:
  --一書兩證檢視
   procedure prc_CreateViewOBookTcert(p_startdate in date,        --統計的開始日期
                                      p_enddate in date)          --統計的結束日期
   is
   v_sql varchar2(2000);
   begin
     v_sql :=
     'create or replace view v_obook_tcert as
       select * from(
           select
           nvl(t11.region,nvl(t22.region,t33.region)) region,
           nvl(t11.site,0) site,
           nvl(t22.useland,0) useland,
           nvl(t33.project,0) project,
           nvl((nvl(t11.site,0)+nvl(t22.useland,0)+nvl(t33.project,0)),0) subtotal--統計某一區域選址、用地、工程的和
          from
            (select t1.專案所在區 region,count(t1.專案所在區) site--統計選址
             from ts_project t1
             where t1.ref_business_id=1 and t1.發證日期 between '||chr(39)||p_startdate||chr(39)||' and '||chr(39)||p_enddate||chr(39)||'
             group by t1.專案所在區) t11
          full join
            (select t2.專案所在區 region,count(t2.專案所在區) useland--統計用地
             from ts_project t2
             where t2.ref_business_id=3 and t2.發證日期 between '||chr(39)||p_startdate||chr(39)||' and '||chr(39)||p_enddate||chr(39)||'
             group by t2.專案所在區) t22
             on t11.region=t22.region
          full join
            (select t3.專案所在區 region,count(t3.專案所在區) project--統計工程
             from ts_project t3
             where t3.ref_business_id in(5,9,11) and t3.發證日期 between '||chr(39)||p_startdate||chr(39)||' and '||chr(39)||p_enddate||chr(39)||'
             group by t3.專案所在區) t33
          on t22.region=t33.region)';
      execute immediate v_sql;
   end prc_CreateViewOBookTcert;
      可以看到變化的地方就是在變數的前後各自加了一個chr(39)(之前的也是有空格的)這個函式就是通過ascii碼得到對應的字元,而39對應的就是空格,這麼修改後就能夠正常動態建立檢視了。

    很多時候大家要是遇到語法什麼的一切都OK,但就是不能動態執行或者建立的時候就想一想是不是這裡出了問題,比如再給遊標動態傳參後使用集合查詢時也會出現這樣的情況。

    目前我還不清楚在這樣的情況下為什麼直接按空格鍵輸入的空格無法使用,而通過chr(39)得到空格可以使用的原因是什麼。也希望能夠得到大家的幫助。