0

我对使用存储过程有点陌生,所以我偶然发现了两个问题。

首先,为什么我不允许这样做?错误信息说:

操作数类型冲突:日期与 int 不兼容

代码 :

@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
4

2 回答 2

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检查也不需要:如果任何时候都没有匹配项(no @domannamnint_doman或 no @keywordin t_ranking),则结果将只是一个空数据集。这应该没问题,调用这个 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 也不是一个坏主意。

于 2012-11-02T10:26:22.760 回答
1

让它工作..!

where ranking_date >= dateadd(mm, datediff(mm, 0, getdate())+0, 0)
and ranking_date < dateadd(mm, datediff(mm, 0, getdate())+1, 0)
于 2012-11-02T10:22:42.030 回答