TSQL函数内部的动态查询无法做到

时间:2016-05-27 04:40:43

标签: sql-server tsql dynamicquery sp-executesql

我试图制作可以根据tablename生成查询的sql server函数。 但是,我收到了这个错误:

  

Msg 557,Level 16,State 2,Line 1   只能在函数内执行函数和一些扩展存储过程。

代码如下:

create function fn_test ( @adate varchar(10), @abc_code
nvarchar(100),@b_id nvarchar(100), @c1 nvarchar(100),
                         @own_retained_id nvarchar(100) , @designation02 nvarchar(100), @currency_id nvarchar(100),
                         @Core_ID nvarchar(100), @Slab_ID nvarchar(100), @Product_03_ID nvarchar(100), 
                         @Category_03_ID nvarchar(100), @PRODUCT_CLASS nvarchar(100),@SEGMENT_CODE nvarchar(100) ) returns @t table(wdate
varchar(10) , sale_code nvarchar(100) ,Branch_code nvarchar(100) ,
CASA nvarchar(100),Owned_Retained_ID nvarchar(100),
            Designation02 nvarchar(100),Currency_ID nvarchar(100) ,Core_ID nvarchar(100) , Slab_ID nvarchar(100), Product_03_ID
nvarchar(100),              Category_03_ID nvarchar(100),PRODUCT_CLASS
nvarchar(100),
             SEGMENT_CODE nvarchar(100), CD_Bal_pkr float )

 as   begin  declare @sql nvarchar(max) set  @sql =  N'select cd.wdate
, a.Sale_Code,r.Branch_code ,cd.CASA ,cd.Owned_Retained_ID  ,
r.Designation02 , a.Currency_ID , cd.Core_ID , cd.Slab_ID ,
a.Product_03_ID , a.Category_03_ID, cd.PRODUCT_CLASS,cd.SEGMENT_CODE,
sum(cd.pkr_open_clr_balance) CD_Bal_pkr  from  lov_rm r  left outer
join   xyz CD on CD.MARKETED_BY=R.Sales_Code left outer  join
BIU_Accounts a  on  a.Acct_Number = cd.ACCT_NUMBER   where  
r.Sales_Code = a.Sale_Code and cd.WDATE = ''' +  @wdate + '''  and
a.Sales_Code_ID_Current in (select RM_ID from LOV_RM where
Designation02 = ''SE-CASA'') and r.Sales_Code like case ' + CHAR(39) +
@sales_code + CHAR(39)+' when '''' then ''%'' when ''None'' then ''%''
else ' + CHAR(39) + @sales_code   +CHAR(39) + ' end AND r.Branch_code
like case ' + CHAR(39) + @branch_id +CHAR(39)+' when '''' then ''%''
when ''None'' then ''%'' else ' + CHAR(39) + @branch_id  +CHAR(39) + '
end  AND cd.CASA like case  ' + CHAR(39) + @casa +CHAR(39)+'  when
'''' then ''%'' when ''None'' then ''%'' else ' + CHAR(39) + @casa
+CHAR(39) + '  end  and r.Designation02   like case ' + CHAR(39) + @designation02 +CHAR(39)+'  when '''' then ''%'' when ''None'' then
''%'' else  ' + CHAR(39) + @designation02 +CHAR(39) + '  end  AND
cd.Owned_Retained_ID like case ' + CHAR(39) + @own_retained_id 
+CHAR(39)+' when '''' then ''%'' when ''None'' then ''%'' else ' + CHAR(39) + @own_retained_id +CHAR(39) + '  end  and a.Currency_ID  
like case  ' + CHAR(39) +  @currency_id  +CHAR(39)+' when '''' then
''%'' when ''None'' then ''%'' else ' + CHAR(39) + @currency_id
+CHAR(39) + ' end  and  cd.Core_ID   like case ' + CHAR(39) +  @Core_ID +CHAR(39)+' when '''' then ''%'' when ''None'' then ''%''
else ' + CHAR(39) +  @Core_ID  +CHAR(39) + ' end  and  cd.Slab_ID 
 like case ' + CHAR(39) +  @Slab_ID +CHAR(39)+' when '''' then ''%''
 when ''None'' then ''%'' else  ' + CHAR(39) + @Slab_ID  +CHAR(39) + '
 end  and  a.Product_03_ID  like case  ' + CHAR(39) + @Product_03_ID 
 +CHAR(39)+' when '''' then ''%'' when ''None'' then ''%'' else ' + CHAR(39) + @Product_03_ID +CHAR(39) + ' end  and   a.Category_03_ID 
 like case ' + CHAR(39) + @Category_03_ID +CHAR(39)+' when '''' then
 ''%'' when ''None'' then ''%'' else  ' + CHAR(39) + @Category_03_ID
+CHAR(39) + '  end  and    cd.PRODUCT_CLASS  like case  ' + CHAR(39) + @PRODUCT_CLASS +CHAR(39)+' when '''' then ''%'' when ''None'' then
 ''%'' else ' + CHAR(39) + @PRODUCT_CLASS +CHAR(39) + '  end  and  
 cd.SEGMENT_CODE like case ' + CHAR(39) +@SEGMENT_CODE +CHAR(39)+' 
 when '''' then ''%'' when ''None'' then ''%'' else  ' + CHAR(39) +
 @SEGMENT_CODE +CHAR(39) + '  end

 group by cd.wdate , a.Sale_Code,  r.Branch_code   ,  cd.CASA ,
cd.Owned_Retained_ID  , r.Designation02 ,  a.Currency_ID , cd.Core_ID
 , cd.Slab_ID , a.Product_03_ID , a.Category_03_ID,cd.PRODUCT_CLASS,
 cd.SEGMENT_CODE  ' 


  print  @sql  EXECUTE sp_executesql @sql  return  end

我正在以select * from fn_portal_biu('2016-05-17', '%', 22,'CA', '%', '%','%' ,'%','%','%','%','%','%' )

执行此功能

1 个答案:

答案 0 :(得分:0)

为什么选择动态sql?没有理由:

select
    cd.wdate,
    a.Sale_Code,r.Branch_code ,cd.CASA ,cd.Owned_Retained_ID  ,
    r.Designation02 , a.Currency_ID , cd.Core_ID , cd.Slab_ID ,
    a.Product_03_ID , a.Category_03_ID, cd.PRODUCT_CLASS,cd.SEGMENT_CODE,
    sum(cd.pkr_open_clr_balance) CD_Bal_pkr 
from  lov_rm r 
left join xyz CD on CD.MARKETED_BY=R.Sales_Code
left join BIU_Accounts a  on  a.Acct_Number = cd.ACCT_NUMBER
where r.Sales_Code = a.Sale_Code and cd.WDATE = @wdate 
    and a.Sales_Code_ID_Current in (select RM_ID from LOV_RM where Designation02 = 'SE-CASA') 
    and r.Sales_Code like case @sales_code when '' then '%' when 'None' then '%' else @sales_code  end
    and r.Branch_code like case @branch_id when '' then '%' when 'None' then '%' else @branch_id end
    and cd.CASA like case  @casa WHEN '' then '%' when 'None' then '%' else @casa end
    and r.Designation02   like case @designation02 when '' then '%' when 'None' then '%' else @designation02 end
    /* and so on */
 group by cd.wdate , a.Sale_Code,  r.Branch_code,  cd.CASA ,
    cd.Owned_Retained_ID  , r.Designation02 ,  a.Currency_ID , cd.Core_ID,
    cd.Slab_ID , a.Product_03_ID , a.Category_03_ID,cd.PRODUCT_CLASS,
    cd.SEGMENT_CODE

这是你的代码没有和版本,除了删除“动态”t-sql。

是的,功能在设计上有很多限制:
https://msdn.microsoft.com/en-us/library/ms191320.aspx

无论如何,写的谓词都很奇怪。为什么“喜欢”如果没有“喜欢”?

...
where r.Sales_Code = a.Sale_Code and cd.WDATE = @wdate 
    and a.Sales_Code_ID_Current in (select RM_ID from LOV_RM where Designation02 = 'SE-CASA') 
    and (@sales_code in ('', 'None') or r.Sales_Code = @sales_code)
    and (@branch_id in ('', 'None') or r.Branch_code = @branch_id)
    and (@casa  in ('', 'None') or cd.CASA = @casa)
    and (@designation02 in ('', 'None') or r.Designation02 = @designation02)
    /* and so on */

此外:为什么id是varchar,当branch_id为NULL时,这段代码应该做什么......

in我建议重写为exists 使用suche一个谓词,最好添加option(recompile),但我想这些表上的索引不多。