如何在存储过程中使用表作为变量

时间:2015-09-30 09:30:18

标签: sql sql-server

我一直在使用这个查询:

SELECT column_name, count(column_name) FROM table_name GROUP by column_name ORDER BY COUNT(column_name) DESC

我用它来检查列中有哪些不同的值以及它们出现的频率。 因为我经常使用这个查询并重复相同的4次:column_name,我就像:为什么不进行存储过程:

CREATE PROCEDURE countcv @table_name VARCHAR(50),@column_name VARCHAR(50)
AS
BEGIN
  SELECT @column_name,COUNT(@column_name) FROM @table_name GROUP BY @column_name ORDER BY COUNT(@column_name)
END

这是我陷入困境的地方,我无法获得变量tablename:

  

必须声明表变量“@table_name”

3 个答案:

答案 0 :(得分:1)

如果你想做这样的事情,你必须使用动态SQL:

CREATE PROCEDURE countcv @table_name sysname, @column_name sysname
AS
BEGIN
    Declare @sql nvarchar(max)
    Set @sql = 'SELECT ' + QUOTENAME(@column_name)+', COUNT(' + QUOTENAME(@column_name)+') 
        FROM ' + QUOTENAME(@table_name)+' 
        GROUP BY ' + QUOTENAME(@column_name)+' ORDER BY COUNT(' + QUOTENAME(@column_name)+')'
    EXEC sp_executesql @sql
END
  • 将sysname用于列名和表名的数据类型(对象名的buitin数据类型,nvarchar(128)的别名)
  • 使用QUOTENAME将分隔符添加到列名和表名

答案 1 :(得分:1)

没有办法直接这样做。您需要使用dynamicSQL方法。假设您传递了正确的表名和列名。下面一个应该工作。

CREATE PROCEDURE countcv @table_name VARCHAR(50),@column_name VARCHAR(50)
AS
BEGIN
declare @SQL nvarchar(max)  
set @SQL  = 'SELECT '+@column_name+',COUNT('+@column_name+') 
             FROM '+@table_name+'  
             GROUP BY '+@column_name+' 
             ORDER BY COUNT('+@column_name+')'

EXEC sp_executesql @SQL
END

答案 2 :(得分:1)

我相信@Julien Vavasseur和@Dark Knight已经解决了你的问题。 但是,我想在此处补充一点,Sql Server 2008通过使用我们可以将表类型变量传递给存储过程来引入Table-Valued Parameter。 e.g。

假设您有一个名为 tblTest 的表格,其中包含以下列

ID  INT,
Name VARCHAR(50)

步骤1:声明新表用户定义类型

CREATE TYPE tblTestType AS TABLE
(
    ID  INT,
    Name VARCHAR(50)
)

第2步:创建以tblTestType为参数的存储过程

CREATE PROCEDURE countcv
(
    @tblName tblTestType readonly
)

AS
INSERT INTO tblTest (ID, Name)
SELECT ID, Name
FROM 
@tblName; 

然后您可以使用DataTable(如果您使用的是C#)并将此数据表作为参数传递给存储过程。(您可以在我提供的链接中找到一个示例)。