在t-sql中参数化查询

时间:2014-06-02 12:28:26

标签: sql sql-server tsql sql-parametrized-query

SELECT TOP @columnCount @columnName 
FROM @tableName

我收到以下错误

  

'@columnCount'附近的语法不正确。

可能出现什么问题?

如果我改为

SELECT TOP (@columnCount) @columnName 
FROM @tableName

我收到以下错误

  

必须声明表变量“@tableName”。

我从C#

运行它

3 个答案:

答案 0 :(得分:3)

安全可靠的方式

DECLARE @columnCount INT = 100
DECLARE @columnName  NVARCHAR(128) = 'YourColumnName'
DECLARE @tableName   NVARCHAR(128) = 'YourTableName'

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = N'SELECT TOP (@columnCount) ' +  QUOTENAME(@columnName) + N' 
            FROM ' + QUOTENAME(@tableName)

EXECUTE sp_executesql @Sql
                     ,N'@columnCount INT'
                     ,@columnCount

答案 1 :(得分:2)

您需要动态SQL才能完成您要执行的操作。

DECLARE @sql VARCHAR(max);
SET @sql = 'SELECT TOP ' + @columnCount + ' ' + @columnName + ' FROM ' + @tableName;
EXEC(@sql);

使用的变量需要适当转换。

documentation

中阅读更多内容

答案 2 :(得分:1)

列列表和表名称不能是参数。但是,由于您是从C#运行它,因此技术上已经在使用动态SQL(除非您使用这些参数调用存储过程,但是这里没有提到正在使用的存储过程,所以现在我将假设没有)。在C#中构建SQL时,需要将列列表和表名称连接到查询中,但仍然可以使用TOP()运算符使用的参数:

SqlConnection _Connection = new SqlConnection("connection string");
SqlCommand _Command = new SqlCommand();
SqlDataReader _Reader = null;

string _Query;
string _TableName = "dbo.MyTable";
string _ColumnList = "Field1, Field2 AS [AliasedName], Field3";
int _NumberOfRows = 12;

_Query = String.Concat("SELECT TOP (@NumberOfRows) ",
    _ColumnList, " FROM ", _TableName);

SqlParameter _NumRows = new SqlParameter("@NumberOfRows", SqlDbType.Int);
_NumRows.Value = _NumberOfRows;

try
{
    _Connection.Open();
    _Reader = _Command.ExecuteReader();
    // do stuff
}
finally
{
    _Reader.Close();
    _Connection.Close();
}

当然,你也可以直接将@NumberOfRows值连接到查询中,但是如果将这个查询多次与ColumnList和TableName的值相同地运行,那么将它作为参数保留将允许重复使用查询计划但更改@NumberOfRows值。