带有默认参数的存储过程

54

我试图基于一个带有预定义参数的查询创建一个存储过程。

当我重构为创建存储过程并执行存储过程时,它会显示参数未提供。 有人可以告诉我为什么吗?

我知道我错过了一些关键点,但在处理代码后,我需要专家的帮助。

这是我的代码(缩短版):

Alter Procedure [Test]
    @StartDate AS varchar(6), 
    @EndDate AS varchar(6)
AS
    Set @StartDate = '201620' --Define start YearWeek
    Set @EndDate  = (SELECT CAST(DATEPART(YEAR,getdate()) AS varchar(4)) + CAST(DATEPART(WEEK,getdate())-1 AS varchar(2)))

    SELECT 
        *
    FROM
        (SELECT DISTINCT 
             [YEAR], [WeekOfYear] 
         FROM 
             [dbo].[DimDate] 
         WHERE 
             [Year] + [WeekOfYear] BETWEEN @StartDate AND @EndDate) dimd
    LEFT JOIN 
        [Schema].[Table1] qad ON (qad.[Year] + qad.[Week of the Year]) = (dimd.[Year] + dimd.WeekOfYear)

运行该程序时出现以下提示:

消息201,级别16,状态4,过程test,第0行
Procedure or function 'test' expects parameter '@StartDate', which was not supplied.


1
如果你在 T-SQL 中设置了 @StartDate 和 @EndDate,为什么还要将它们作为参数请求呢?只需在 T-SQL 中声明它们即可正常运行。 - jellz77
你的标题提到了默认值,但实际上你并没有指定任何值。你可以在声明中添加= null来为它们指定默认值,然后就可以在不传递参数的情况下执行它们了。现有的答案已经指出了一些其他的修复方法。 - shawnt00
1
抱歉,这个周末很忙,我不得不使用varchar的原因是它连接到的DIM日期表将WeekOfYear和Year存储为nvarchar,并且加载的数据来自Google Analytics,其输出为文本。这只是一个简单的临时报告,但我将来会考虑转换。 - TSQL_Newbie
2个回答

94

我使用了预定义的参数。

这些参数并不是在代码逻辑中“预定义”的。但作为存储过程(SP)的参数,它们没有默认值且是必需的。为了避免显式传递这些参数,您需要在 SP 定义中定义默认值:

Alter Procedure [Test]
    @StartDate AS varchar(6) = NULL, 
    @EndDate AS varchar(6) = NULL
AS
...

NULL值或空字符串或其他更合理的值-由您决定。这并不重要,因为您在SP的第一行中覆盖了这些参数的值。

现在你可以在不传递任何参数的情况下调用它,例如exec dbo.TEST


为了让它与函数一起工作,您必须调用它并提供“default”占位符:SELECT TestFunction(default) 参考 - estani

4
我会用以下两种方法之一进行操作。由于您在 t-SQL 代码中设置了起始和结束日期,因此我不会在存储过程中要求参数。 选项1
Create Procedure [Test] AS
    DECLARE @StartDate varchar(10)
    DECLARE @EndDate varchar(10)
    Set @StartDate = '201620' --Define start YearWeek
    Set @EndDate  = (SELECT CAST(DATEPART(YEAR,getdate()) AS varchar(4)) + CAST(DATEPART(WEEK,getdate())-1 AS varchar(2)))

SELECT 
*
FROM
    (SELECT DISTINCT [YEAR],[WeekOfYear] FROM [dbo].[DimDate] WHERE [Year]+[WeekOfYear] BETWEEN @StartDate AND @EndDate ) dimd
    LEFT JOIN [Schema].[Table1] qad ON (qad.[Year]+qad.[Week of the Year]) = (dimd.[Year]+dimd.WeekOfYear)

Option 2

Create Procedure [Test] @StartDate varchar(10),@EndDate varchar(10) AS

SELECT 
*
FROM
    (SELECT DISTINCT [YEAR],[WeekOfYear] FROM [dbo].[DimDate] WHERE [Year]+[WeekOfYear] BETWEEN @StartDate AND @EndDate ) dimd
    LEFT JOIN [Schema].[Table1] qad ON (qad.[Year]+qad.[Week of the Year]) = (dimd.[Year]+dimd.WeekOfYear)

然后运行 exec test '2016-01-01','2016-01-25'

此外,您可能希望将您的 varchar 设置为适当的字符数...我使用了10个字符,但根据您的原始帖子,您可能需要6个字符。 - jellz77

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接