繁体   English   中英

数据库名称作为存储过程中的参数 SQL 服务器

[英]Db Name as parameter in stored procedure SQL Server

我希望将我的数据库名称作为参数传递给存储过程,并且我希望在 where 条件下使用它来设置存储过程的数据库。 但我得到一个错误:

'.' 附近的语法不正确

示例代码

Create proc [dbo].[stored_procedure_one]
    @variable1 int,
    @dbname varchar(10)
as
begin
    select * 
    from @dbname..table_name
End

有人可以建议我如何解决这个问题吗?

您将需要使用动态sql来执行类似以下操作。

Create proc [dbo].[stored_procedure_one]
    @variable1 int,
    @dbname    SYSNAME  --<-- use appropriate data type for object names
as
begin
  DECLARE @Sql NVARCHAR(MAX);

 SET @Sql = N' select * from ' + QUOTENAME(@dbname) + N'..table_name'

 Exec sp_executesql @Sql

End

还可以使用QUOTENAME()函数来保护自己免受可能的sql-injection攻击。

只是为了提供一个替代方案,有趣的是EXEC可以将字符串作为要执行的内容,例如:

DECLARE @sp nvarchar(255) = N'sys.sp_who2';
EXEC @sp;

它还可以带参数,例如

DECLARE @sp nvarchar(255) = N'sys.sp_who2';
EXEC @sp 'active';

因此,我们可以使用以下方法动态构建运行命令的上下文:

DECLARE @dbname sysname = N'tempdb';
DECLARE @context nvarchar(1000) = QUOTENAME(@dbname)
  + N'.sys.sp_executesql';

DECLARE @sql nvarchar(max) = N'SELECT DB_NAME();';

EXEC @context @sql;

你也可以传递参数:

DECLARE @dbname sysname = N'tempdb';
DECLARE @context nvarchar(1000) = QUOTENAME(@dbname)
  + N'.sys.sp_executesql';

DECLARE @sql nvarchar(max) = N'SELECT DB_NAME(), @x;';

EXEC @context @sql, N'@x int', 5;

这种方法确实简化了诸如在各处连接数据库名称、避免特定于数据库的函数(如 object_name)之类的事情,并确保您的整个命令在另一个数据库中运行 您也可以跨链接服务器执行此操作,例如:

DECLARE @server sysname = N'linked_server';
DECLARE @dbname sysname = N'tempdb';
DECLARE @context nvarchar(1000) = QUOTENAME(@server)
  + N'.' + QUOTENAME(@dbname)
  + N'.sys.sp_executesql';
...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM