如何使用动态from子句创建存储过程

时间:2009-01-07 15:58:53

标签: sql-server

我遇到了一个应用程序的问题,该应用程序一遍又一遍地使用相同的存储过程来填充下拉列表中的人员信息。问题是,随着数据的变化,人们有时不再存在。我有两个可供选择的视图,但我想根据应用程序的状态动态更改正在使用的视图。

对于新记录,我只想看到当前的人。如果我正在更新现有记录,我可能希望看到所有人,因为现有记录可能会引用不再是当前记录的人。

如何将视图名称传递给我的存储过程,以便我可以从中进行选择?

我已经尝试添加:

@view varchar(50)

select a, b from @view

但我得到一个错误,说明我必须声明变量@view。

这甚至可以吗?

7 个答案:

答案 0 :(得分:2)

如果您只使用两个视图并且知道它们的名称,则可以将一个位参数传递给过程。

@useFirstView bit

IF @useFirstView = 1 
   -- select from firstView
ELSE
   -- select from secondView

答案 1 :(得分:2)

您可以在SP中创建语句并致电:

exec sp_executesql @sql

答案 2 :(得分:1)

我想知道完全相同的事情,我在MSDN论坛中遇到了这个帖子:

http://social.msdn.microsoft.com/Forums/en-US/transactsql/thread/fa523f21-5a8b-421f-99ce-9bb2ec30e848

最后看看萨米萨米尔的答案 - 至少对我来说它提供了一个完美的解决方案,我希望它能为你做同样的事情。

动态SQL在固定数量的表/视图之间进行动态选择,这些表/视图具有相同的字段,听起来不对 - 难以调试和错误/黑客攻击。

一切顺利。

答案 3 :(得分:0)

您可以使用动态SQL来解决您的问题。

DECLARE @sqlCommand varchar(1000)
SET @sqlCommand = 'SELECT a, b from FROM ' + @view
EXEC (@sqlCommand)

但我不认为这是最好的解决方案。你应该有一个像

这样的查询
If @IsActiveFlag = TRUE THEN
  SELECT * FROM People WHERE IsActive = 1
ELSE
  SELECT * FROM People
ENDIF

答案 4 :(得分:0)

您是否尝试在存储过程中声明变量并将参数指定为值?

例如,假设您有一个名为@view的参数:

  

声明@viewName nvarchar(50)

     

设置@viewName = @view

答案 5 :(得分:-1)

你只是错过了变量的声明

DECLARE @view VARCHAR(50)
SET @view = 'myView'
SELECT a,b FROM @view

或者如果在存储过程中使用

CREATE PROCEDURE SelectFromView
{
    @view VARCHAR(50)
}
AS
BEGIN

    DECLARE @sqlCommand varchar(1000)
    SET @sqlCommand = 'SELECT a, b from FROM ' + @view
    EXEC (@sqlCommand)

END

请注意SQLInjection attacs,如前所述。

[编辑] 使用Nathan Koop的代码纠正了动态sql创建的使用,thx。 [/编辑]

答案 6 :(得分:-1)

你的想法很诱人,但这不是支持的(为什么这里的人甚至建议DECLARE变量?),换句话说,你做错了。

FROM子句接受表/视图/函数名称(硬编码,而不是来自varchar变量)或表变量。 表变量如下所示:

DECLARE @table TABLE (a int, b int).

请注意,它的类型为TABLE,而不是VARCHAR。之后你可以这样做:

SELECT a,b FROM @table.

但显然这不是你想要的。我建议使用sp_executesql(仅当您设置了视图/表名,而不是来自用户数据或类似名称)或IF-ELSE语句。