2012-11-01 17 views
0

我對使用存儲過程有點新,所以我偶然發現了兩個問題。SQL Server:如何將幾行返回到一個變量

首先爲什麼我不允許這樣做?錯誤消息說:

操作數類型衝突:日期與詮釋

代碼不兼容:

@time date OUTPUT 

SELECT @time = ranking_date 
FROM [dbo].[t_ranking] 
WHERE ranking_date <= DATEDIFF(day, @todaysDateminusthirty, @todaysdate) 
    AND ranking_keyword = @keyword 
    AND ranking_id_doman = @domainID 

勇往直前我怎麼能回到我的結果作爲一個完整的數據集?而不是保存到兩個變量?或者他們可以擁有多行?

ALTER PROCEDURE [dbo].[fetchRankingData] 
-- Add the parameters for the stored procedure here 
@domannamn [varchar](100), 
@keyword [varchar](100), 
@rankingen [decimal](6,2) OUTPUT, 
@time date OUTPUT 

AS 
DECLARE @domainID int 
DECLARE @todaysDateminusthirty datetime 
DECLARE @todaysdate datetime 

BEGIN 
SET NOCOUNT ON; 

IF EXISTS(SELECT 1 FROM [dbo].[t_doman] WHERE doman_namn = @domannamn) 
BEGIN 
set @todaysdate = getdate() 
set @todaysDateminusthirty = DATEADD(day,-30,@todaysdate) 

SELECT @domainID = doman_id FROM [dbo].[t_doman] WHERE doman_namn = @domannamn 

IF EXISTS(SELECT 1 FROM [dbo].[t_ranking] WHERE ranking_id_doman = @domainID AND ranking_keyword = @keyword) 
BEGIN 
    SELECT @rankingen = ranking_position FROM 
     [dbo].[t_ranking] WHERE ranking_keyword = @keyword 
      AND ranking_id_doman = @domainID 
    SELECT @time = ranking_date FROM 
     [dbo].[t_ranking] WHERE ranking_date <= DATEDIFF(day,@todaysDateminusthirty,@todaysdate) AND ranking_keyword = @keyword 
      AND ranking_id_doman = @domainID  
END 
END 
END 
+2

1)你會得到這個異常,因爲你試圖比較一個日期時間字段和int,因爲'DATEDIFF(day..'返回一個int。 –

+1

「我對使用存儲過程有點新鮮」 - 你看過Books在線? –

+0

@MitchWheat是的,因此,我設法得到了這麼多!但他們不包括返回多個變量在一個...也許我應該去一個數據集,包含許多變量;) – 8bitcat

回答

2

首先,爲什麼要比較日期和天數?這就是DATEDIFF(DAY, ...)本質上的回報,即兩個日期之間的天數。也許你的意思

ranking_date <= @todaysDateminusthirty 

ranking_date <= @todaysdate 

或(仍然較好,可能)

ranking_date BETWEEN @todaysDateminusthirty AND @todaysdate 

至於你的第二個問題,不,你不能存儲到行標量,但你可以讓你的存儲過程返回一個結果集:只需使用返回行的SELECT語句(與初始化變量相反),換句話說,一個「正常」的SELECT語句。

您的存儲過程的目的對我來說不是很清楚,所以我的建議可能與它沒有很好的關聯。但是,這也可能是一樣的,因爲你也需要做你的功課,不是嗎。只是,你可能需要一個很好的起點,下面應該(希望)爲您提供一個:

SELECT 
    ranking_position, 
    ranking_date 
FROM dbo.t_ranking 
WHERE ranking_keyword = @keyword 
    AND ranking_date BETWEEN DATEADD(day, -30, GETDATE()) AND GETDATE() 
    AND ranking_id_doman IN (
    SELECT doman_id FROM dbo.t_doman WHERE doman_namn = @domannamn 
) 
; 

你可以看到,我取代@todaysDateminusthirty@todaysdate直接與相應的表達式查詢。如果你認爲你需要這些變量(例如,你可能正在考慮擴展這個過程,所以變量可以在身體的其他部分重新使用),那麼就把它們留在原地。但是,您的存儲過程似乎並不需要它們。

還要注意,不需要你IF EXISTS檢查之一:如果沒有匹配的任何一點(在t_doman沒有@domannamnt_ranking沒有@keyword),其結果將是隻是一個空的數據集。這應該沒問題,調用這個SP的模塊應該檢查結果集中是否存在行,以解決這種情況。

最終,那麼,整個聲明看起來是這樣的:

ALTER PROCEDURE [dbo].[fetchRankingData] 
@domannamn [varchar](100), 
@keyword [varchar](100) 
/* the OUTPUT parameters are removed as no longer needed apparently */ 
AS 
/* no apparent need for additional variables either */ 
BEGIN 

SET NOCOUNT ON; 

SELECT 
    ranking_position, 
    ranking_date 
FROM dbo.t_ranking 
WHERE ranking_keyword = @keyword 
    AND ranking_date BETWEEN DATEADD(day, -30, GETDATE()) AND GETDATE() 
    AND ranking_id_doman IN (
    SELECT doman_id FROM dbo.t_doman WHERE doman_namn = @domannamn 
) 
; 

END 

我希望我不會冒犯你(太多了)時,我想借此機會,建議你開始閱讀更多的存儲話題手冊和其他地方的程序。 Books Online應該給你足夠的好材料來開始你的改進,瀏覽/搜索StackOverflow也不是一個壞主意。

1

得到它的工作..!

where ranking_date >= dateadd(mm, datediff(mm, 0, getdate())+0, 0) 
and ranking_date < dateadd(mm, datediff(mm, 0, getdate())+1, 0) 
+1

糟糕,我正在清理我的答案太長,並且在有關新答案的通知時我沒有注意(我猜這肯定是有的)。我希望你不覺得它對你完全沒用,但無論如何,你自己做好解決方案! –

+0

@AndriyM嗨!沒有冒犯建設性的批評是最好的!非常感謝你的幫助!真的寫得很好,你怎麼解決了domain_id,沒有看到一個來的.. !!!謝謝! – 8bitcat

相關問題