2012-02-04 58 views
0

我的存儲過程:輸入變量作爲存儲過程語句

ALTER PROCEDURE [dbo].[Perdate] 
@D_Data as nvarchar(999) 

AS 

SELECT 'Total'= SUM(CAST(TBL_Stock.R_TotalPrice as decimal(18,2))),(convert(varchar,TBL_Stock.D_Datepush,105)) as Date 
FROM  TBL_Stock 
GROUP BY (convert(varchar,TBL_Stock.D_Datepush,105)) 
Having  (convert(varchar,TBL_Stock.D_Datepush,105)) = @D_Data 

我想知道這是否是可能的變量(@D_Data)設置爲一樣的東西:

'02-03-2012' or (convert(varchar,TBL_Stock.D_Datepush,105)) = '02-04-2012' 

所以有子句將是:

HAVING (convert(varchar, TBL_Stock.D_Datepush, 105)) = '02-03-2012' 
     OR (convert(varchar, TBL_Stock.D_Datepush, 105)) = '02-04-2012' 

所以我的想法是有(在我的VB.net項目)一個字符串這可能會動態地改變存儲過程「未來」

+3

我沒有時間給一個完整的答案,但有一點是:爲什麼使用HAVING當它不包含聚合?把條件放在WHERE子句中!另外,什麼DBMS和什麼版本? Microsoft SQL Server 2008還是什麼? – ErikE 2012-02-04 02:25:44

+0

你會想看看動態SQL。 http://msdn.microsoft.com/en-us/library/ms188001.aspx。如果你走這條路線,你將失去使用存儲過程(如計劃緩存)的許多好處。有可能是你想要做的事情有更好的解決方案,那麼你真正想做什麼? – 2012-02-04 02:37:25

回答

0

好像你想要做SQL注入,以便你的輸入參數「粘合到」你的proc中構建的TSQL。這是一個非常糟糕的想法(see SQL Injection discussion here)。

但是好消息,動態SQL是不需要的。使用表函數來解析傳入的字符串,以便它可以在proc中加入。

create table TBL_Stock(R_TotalPrice decimal(18,2), D_Datepush datetime) 
insert into TBL_Stock(R_TotalPrice,D_datepush) values(1000,'1/1/2012') 
insert into TBL_Stock(R_TotalPrice,D_datepush) values(200,'1/2/2012') 
insert into TBL_Stock(R_TotalPrice,D_datepush) values(30,'1/3/2012') 
insert into TBL_Stock(R_TotalPrice,D_datepush) values(4,'1/4/2012') 
GO 

CREATE FUNCTION dbo.SplitDates(@String varchar(8000), @Delimiter char(1))  
returns @temptable TABLE (dt datetime)  
as  
begin  
    declare @idx int  
    declare @slice varchar(8000)  

    select @idx = 1  
     if len(@String)<1 or @String is null return  

    while @idx!= 0  
    begin  
     set @idx = charindex(@Delimiter,@String)  
     if @idx!=0  
      set @slice = left(@String,@idx - 1)  
     else  
      set @slice = @String  

     if(len(@slice)>0 AND isDate(@slice) = 1) 
      insert into @temptable(dt) values(@slice)  

     set @String = right(@String,len(@String) - @idx)  
     if len(@String) = 0 break  
    end 
return  
end 
GO 

--test function 
select * from dbo.SplitDates('1/1/2012,1/2/2012',',') 
GO 

create PROCEDURE Perdate @D_Data as nvarchar(2000) 
AS 
select 
    PushDate=z.dt, 
    'Total'= SUM(s.R_TotalPrice) 
from 
    dbo.splitDates(@D_Data,',') z 
    join TBL_Stock s on s.D_datepush = z.dt 
group by 
    z.dt 
GO 

--Test proc 
select * from TBL_Stock 
exec Perdate '1/1/2012' 
exec Perdate '1/1/2012,1/2/2012' 
exec Perdate '1/1/2012,1/4/12' 

enter image description here

+0

那是天才@斯卡爾。你提供給我的想法並不完全是我想要的,但所有的代碼都幫助了我很多,最終我可以解決這個問題。謝謝 – 2012-02-07 18:51:38