语法问题:在存储过程中使用变量

时间:2009-01-19 11:33:07

标签: sql-server visual-studio sql-server-2005 stored-procedures

任何人都可以告诉下面的代码有多正确。我试着创建一个存储过程,返回名称传递给它的表的行数。

CREATE PROCEDURE spROWCOUNTER
(
    @tablename nvarchar(20)
    @rowCountVal int OUTPUT
)

AS

DECLARE @strQuery nvarchar(300)

SET @strQuery = 'SELECT @rowCountVal=COUNT(*) FROM '+@tablename

EXEC(@strQuery)

RETURN @rowCountVal

错误消息:

  • '@rowCountVal'附近的语法不正确
  • 必须声明标量变量'@tablename'
  • 必须声明标量变量'@rowCountVal'

而下面的代码工作正常

ALTER PROCEDURE spROWCOUNTER
(
    @rowCountVal int OUTPUT
)

AS

SELECT @rowCountVal=COUNT(*) FROM DEFECT_LOG

RETURN @rowCountVal

6 个答案:

答案 0 :(得分:3)

CREATE PROCEDURE spROWCOUNTER   
    @tablename nvarchar(20),    
    @rowCountVal int OUTPUT
AS

SELECT @rowCountVal = ISNULL(SUM(spart.rows), 0)
FROM sys.partitions spart 
WHERE spart.object_id = object_id(@tablename) AND spart.index_id < 2

RETURN @rowCountVal

答案 1 :(得分:1)

语法问题很容易解决。您的参数之间有缺少逗号(“,”)。插入逗号和存储过程编译:

( @tablename nvarchar(20), @rowCountVal int OUTPUT )

然后,存在主要问题:您无法访问EXEC语句中的@rowCountVal参数。要解决此问题,您可以使用内置存储过程sp_executesql

阅读此good article written by the SQL Server MVP Erland Sommarskog

顺便说一下:你不必“返回”一个变量。返回值通常用于返回某些状态值。如果传递输出参数,则会自动返回。

答案 2 :(得分:1)

我会使用sp_executesql而不是exec。然后你可以将@rowCountVal作为输出变量传入动态sql。

create PROCEDURE spROWCOUNTER
(
    @tablename nvarchar(20),
    @rowCountVal int OUTPUT
)

AS

DECLARE @strQuery nvarchar(300)

SET @strQuery = 'SELECT @rowCountVal = COUNT(*) FROM '+@tablename

exec sp_executesql @strQuery, N'@tablename nvarchar(20), @rowCountVal int OUTPUT',   @tablename = @tablename, @rowCountVal = @rowCountVal output


RETURN @rowCountVal

答案 3 :(得分:1)

在execute语句中,您可以使用临时表来共享数据:

CREATE PROCEDURE spROWCOUNTER   
    @tablename nvarchar(20),    
    @rowCountVal int OUTPUT
AS

CREATE TABLE #Result( Rows INT )
EXEC( 'INSERT INTO #Result( Rows ) SELECT COUNT(*) FROM ' + @tablename )

SELECT @rowCountVal = Rows FROM #Result

RETURN @rowCountVal

答案 4 :(得分:1)

如果您想将行计数作为一项功能,您还可以检查Speeding up the Performance of Table Counts in SQL Server 2005

在文章中提供的函数显然比调用非常大的表的count(*)快。

答案 5 :(得分:0)

是的,我错过了逗号。但即使在此之后,该值也不会存储在@rowCountVal

SET @strQuery = 'SELECT @rowCountVal=COUNT(*) *FROM '+ @tablename

EXEC(@strQuery)

查询不返回也不显示任何值。


顺便说一句,我想过从其他存储过程中调用这个proc来获取rowcounts。 以下陈述是否有效:

set @rCount = exec spROWCOUNTER('DEFECT_LOG')