我想编写一个存储过程,它将使用一个参数,它将是表名。
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附近说错误的语法。
答案 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表示}}':
||
这仍然可能没有你想要的 - 但是在创建过程时它可能不会产生语法错误(但它可能会在运行时产生错误)。