Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何使用dynamicfrom子句创建存储过程_Sql Server - Fatal编程技术网

Sql server 如何使用dynamicfrom子句创建存储过程

Sql server 如何使用dynamicfrom子句创建存储过程,sql-server,Sql Server,我遇到了一个应用程序的问题,该应用程序反复使用相同的存储过程来填充下拉列表中的人员信息。问题是,随着数据的变化,有时人们不再在场。我有两个视图可供选择,但我希望根据应用程序的状态动态更改正在使用的视图 对于新记录,我只想看到当前的人。如果我正在更新现有记录,我可能希望看到所有人,因为现有记录可能引用不再是当前记录的人 如何将视图名称传递到存储过程中,以便从中进行选择 我已经尝试添加: @view varchar(50) select a, b from @view 但是我得到一个错误,声明我

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

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

如何将视图名称传递到存储过程中,以便从中进行选择

我已经尝试添加:

@view varchar(50)

select a, b from @view
但是我得到一个错误,声明我必须声明变量@view


甚至可以这样做吗?

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

@useFirstView bit

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

如果只使用两个视图,并且知道它们的名称,则只需向过程传递一个位参数即可

@useFirstView bit

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

您可以在SP中创建语句并调用:

exec sp_executesql @sql

您可以在SP中创建语句并调用:

exec sp_executesql @sql

您可以使用动态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

您可以使用动态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

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

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

声明@viewName nvarchar(50)

设置@viewName=@view


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

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

声明@viewName nvarchar(50)

设置@viewName=@view


您只是错过了变量的声明

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攻击

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

您只是错过了变量的声明

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攻击

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

你的想法很诱人,但这不受支持(为什么这里的人甚至建议声明一个变量?)

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

DECLARE @table TABLE (a int, b int).
注意,它的类型是TABLE,而不是VARCHAR。之后,您可以执行以下操作:

SELECT a,b FROM @table.

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

您的想法很诱人,但这不受支持(为什么这里的人甚至建议声明变量?),或者换句话说,您的做法是错误的

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

DECLARE @table TABLE (a int, b int).
注意,它的类型是TABLE,而不是VARCHAR。之后,您可以执行以下操作:

SELECT a,b FROM @table.

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

我想知道完全相同的事情,我在MSDN论坛上遇到了以下线程:

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

在具有相同字段的固定数量的表/视图之间进行动态选择的动态SQL听起来不太正确-很难调试,而且容易发生错误/黑客攻击


祝你一切顺利。

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

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

在具有相同字段的固定数量的表/视图之间进行动态选择的动态SQL听起来不太正确-很难调试,而且容易发生错误/黑客攻击


最好。

使用此方法可以帮助您避免使用动态SQL。动态SQL可能导致SQL注入攻击。这对你来说可能是个问题,也可能不是。我用了这个原则,它起作用了。即使存在代码重复,这也是最快/最简单的修复方法,并且非常容易理解。谢谢你的回复!使用此方法可以帮助您避免使用动态SQL。动态SQL可能导致SQL注入攻击。这对你来说可能是个问题,也可能不是。我用了这个原则,它起作用了。即使存在代码重复,这也是最快/最简单的修复方法,并且非常容易理解。谢谢你的回复!是的,我试过了,但对我不起作用。它产生了3个错误,而不是1个。当然,它提供了更多错误,@view必须在这里声明并设置为@viewName。是的,我尝试了这个,但它对我无效。它会产生3个错误,而不仅仅是1个。当然,它会提供更多错误,@view必须在此处声明并设置为@viewName。非常小心,黑客可能会通过“人员;删除表人员;”来破坏/攻击/接管您的数据库。这不会发生。@view将在一些.net代码中设置,用户输入无法访问。请小心,黑客可能会通过“人员;删除表人员;”来破坏/攻击/接管您的数据库。这不会发生。@view将在某些.net代码中设置,用户输入无法访问。您还可以参数化