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代码中设置,用户输入无法访问。您还可以参数化