【问题标题】:SQL Server stored procedure need to declare scalar variableSQL Server 存储过程需要声明标量变量
【发布时间】:2013-10-20 10:52:25
【问题描述】:

我正在尝试这个存储过程:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[spx_Pager]
    @PageNo int = 1,
    @ItemsPerPage int = 2,
    @TotalRows int out
AS
BEGIN
  SET NOCOUNT ON
  DECLARE
    @StartIdx int,
    @SQL nvarchar(max),  
    @SQL_Conditions nvarchar(max),  
    @EndIdx int

    IF @PageNo < 1 SET @PageNo = 1
    IF @ItemsPerPage < 1 SET @ItemsPerPage = 10

    SET @StartIdx = (@PageNo -1) * @ItemsPerPage + 1
    SET @EndIdx = (@StartIdx + @ItemsPerPage) - 1
    SET @SQL = 'SELECT FilePath
                FROM (
                SELECT  ROW_NUMBER() OVER(ORDER BY ID) AS Row, * 
                      FROM  tblFiles ) AS tbl WHERE  Row >= ' 
                        + CONVERT(varchar(9), @StartIdx) + ' AND
                       Row <=  ' + CONVERT(varchar(9), @EndIdx)
    EXEC sp_executesql @SQL

    SET @SQL = 'SELECT @TotalRows=COUNT(*) FROM tblFiles' 
    EXEC sp_executesql 
        @query = @SQL, 
        @params = N'@TotalRows INT OUTPUT', 
        @TotalRows = @TotalRows OUTPUT 
END

它运行良好,但我尝试使用视图对其进行扩展,这里是代码

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

alter PROCEDURE [dbo].[spx_Pager]
    @PageNo int = 1,
    @ItemsPerPage int = 2,
    @TotalRows int out,
    @fname varchar(50),
    @mname varchar(50),
    @lname varchar(50),
    @qfr varchar(10)
AS
BEGIN
  SET NOCOUNT ON
  DECLARE
    @StartIdx int,
    @SQL nvarchar(max),  
    @SQL_Conditions nvarchar(max),  
    @EndIdx int

    IF @PageNo < 1 SET @PageNo = 1
    IF @ItemsPerPage < 1 SET @ItemsPerPage = 10

    SET @StartIdx = (@PageNo -1) * @ItemsPerPage + 1
    SET @EndIdx = (@StartIdx + @ItemsPerPage) - 1
    SET @SQL = N'SELECT path_front
                FROM (
                SELECT  ROW_NUMBER() OVER(ORDER BY fname) AS Row, * 
                      FROM  searcherview 
                      where (fname = @fname or @fname = '') and (mname = @mname or @mname = '') and (lname = @lname or @lname = '') and (qualifier = @qfr or @qfr = '')
                       ) AS tbl WHERE  Row >= ' 
                        + CONVERT(varchar(9), @StartIdx) + ' AND
                       Row <=  ' + CONVERT(varchar(9), @EndIdx)
    EXEC sp_executesql @SQL

    SET @SQL = 'SELECT @TotalRows=COUNT(*) FROM searcherview' 
    EXEC sp_executesql 
        @query = @SQL, 
        @params = N'@TotalRows INT OUTPUT', 
        @TotalRows = @TotalRows OUTPUT 
END

但是当我尝试执行存储过程时,会返回一个错误提示

必须声明标量变量“@fname”

【问题讨论】:

    标签: sql-server stored-procedures


    【解决方案1】:

    如果您在 sp_executesql 中使用变量,则需要定义它们,就像您在第二个 sp_executesql 中所做的那样

    @params = N'@TotalRows INT OUTPUT', 
    @TotalRows = @TotalRows OUTPUT 
    

    所以你需要添加

    @params = N'@fname varchar(50), @mname varchar(50), @lname varchar(50), @qualifier varchar(10)',
    @fname = @fname, @mname = @mname, @lname=@lname, @qualifier = @qfr
    

    给您的第一个sp_executesql 电话

    虽然你为什么要使用动态 SQL 对我来说并不是很明显。

    如果您使用的是 SQL 2012,您可能对 OFFSET 和 FETCH 命令感兴趣

    【讨论】:

    • 我正在使用 2008 r2 我尝试了您的建议,但它显示 Msg 102, Level 15, State 1, Procedure spx_Pager, Line 34 Incorrect syntax near '@params'.
    • @angelogogo 你可能错过了 SQL 后面的逗号
    【解决方案2】:
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    
    alter PROCEDURE [dbo].[spx_Pager](
        @PageNo int = 1,
        @ItemsPerPage int = 2,
        @TotalRows int out,
        @fname varchar(50),
        @mname varchar(50),
        @lname varchar(50),
        @qfr varchar(10)
        )
    AS
    BEGIN
      SET NOCOUNT ON
      DECLARE
        @StartIdx int,
        @SQL nvarchar(max),  
        @SQL_Conditions nvarchar(max),  
        @EndIdx int
    
        IF @PageNo < 1 SET @PageNo = 1
        IF @ItemsPerPage < 1 SET @ItemsPerPage = 10
    
        SET @StartIdx = (@PageNo -1) * @ItemsPerPage + 1
        SET @EndIdx = (@StartIdx + @ItemsPerPage) - 1
        SET @SQL = N'SELECT path_front
                    FROM (
                    SELECT  ROW_NUMBER() OVER(ORDER BY fname) AS Row, * 
                          FROM  searcherview 
                          where (fname = @firstname or @firstname = '') and (mname = @midname or @midname = '') and (lname = @lastname or @lastname = '') and (qualifier = @quali or @quali = '')
                           ) AS tbl WHERE  Row >= ' 
                            + CONVERT(varchar(9), @StartIdx) + ' AND
                           Row <=  ' + CONVERT(varchar(9), @EndIdx)
        EXEC sp_executesql @SQL,
        @params = N'@firstname varchar(50), @midname varchar(50), @lastname varchar(50), @quali varchar(10)',
        @firstname = @fname, @midname = @mname, @lastname=@lname, @quali = @qfr
    
        SET @SQL = 'SELECT @TotalRows=COUNT(*) FROM searcherview' 
        EXEC sp_executesql 
            @query = @SQL, 
            @params = N'@TotalRows INT OUTPUT', 
            @TotalRows = @TotalRows OUTPUT 
    END
    

    最终的代码,感谢@podiluska

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-08
      • 2016-04-17
      相关资源
      最近更新 更多