动态SQL(将表名作为参数传递)

时间:2009-08-24 22:07:59

标签: sql-server tsql

我想编写一个存储过程,它将使用一个参数,它将是表名。

E.g:

@tablename << Parameter

SELECT * FROM @tablename

这怎么可能?

我写了这个:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[GetAllInterviewQuestions]
@Alias varchar = null
AS
BEGIN
Exec('Select * FROM Table as ' @Alias) 
END

但它在@Alias附近说错误的语法。

5 个答案:

答案 0 :(得分:19)

好吧,首先你从字符串中省略了'+'。这种做事方式远非理想,但你可以做到

DECLARE @SQL varchar(250)
SELECT @SQL = 'SELECT * FROM ' + QuoteName(@Alias)
Exec(@SQL)
但是,我强烈建议你重新考虑如何做到这一点。生成动态SQL通常会导致SQL注入漏洞,并使SQL Server(和其他数据库)更难以找到处理查询的最佳方法。如果你有一个可以返回任何表的存储过程,那么它实际上几乎没有从它作为存储过程中获益,因为它无法在优化方面做很多事情,而且你是在很大程度上也贬低了安全利益。

答案 1 :(得分:4)

你必须这样做: exec('select * from '+@tablename+' where...')

但请确保您完全了解SQL注入攻击等风险。一般来说,如果数据库设计得很好,你就不应该使用这样的东西。

答案 2 :(得分:3)

你不是说

Exec('SELECT * FROM ' + @tableName) 

此外,您得到的错误是因为您在@Alias之前忘记了+

答案 3 :(得分:1)

通常,必须参数化表名称表明您应该重新考虑数据库模式。如果您从许多不同的表中提取面试问题,最好创建一个表,其中列以不同表格的方式区分问题。

答案 4 :(得分:0)

SQL的大多数实现都不允许您通过参数指定结构元素 - 表名,列名,按列排序等。您必须使用动态SQL来参数化查询的这些方面。

但是,看看SQL,你有:

Exec('SELECT * FROM Table AS ' @Alias)

当然,这意味着代码只能从名为'Table'的表中进行选择,并且您需要将@Alias与它连接 - 并且在许多SQL方言中,连接由'{{1表示}}':

||

这仍然可能没有你想要的 - 但是在创建过程时它可能不会产生语法错误(但它可能会在运行时产生错误)。