首页 > 解决方案 > 将数据库名称作为参数传递给 sp_executesql 以在查询中替换

问题描述

我正在尝试执行连接来自不同数据库的表的 SQL 语句。我想知道是否可以以任何方式替换通过 sp_executesql 作为参数传递的数据库名称?

exec sp_executesql N'SELECT
              A.* FROM TableA A
              INNER JOIN @dbName..TableB B ON A.C1 = B.C1
              WHERE B.C2 = @ptr',N'@BillingRunID int,@AccountID int,@dbName nvarchar(4000)',@ptr=1001,@dbName=N'Student'

我遇到的问题是我在 .net 项目中有查询,并且在其他过程中使用 sp_executesql 调用它,因为 SQL 不能作为 proc 或任何其他方式移动到数据库中。有没有办法解决这个问题?

标签: sql-server

解决方案


您不能参数化对象名称,它必须被安全地注入。你可以这样实现:

DECLARE @dbname sysname, --Obviously this'll be assigned somewhere
        @SQL nvarchar(MAX),
        @CRLF nchar(2) = NCHAR(13) + NCHAR(10);

SET @SQL = N'SELECT A.*' + @CRLF +
           N'FROM dbo.Table A' + @CRLF +
           N'     INNER JOIN ' + QUOTENAME(@dbName) + N'.dbo.TableB B On A.C1 = B.C1' + @CRLF +
           N'WHERE B.C2 = @ptr;';
--PRINT @SQL; --Your best friend
--Oddly, only @ptr is in your script, but it isn't defined in the second parameter.
--I therefore don't know what data type it needs to be.
EXEC sys.sp_executesql @SQL, N'@prt {Your Datatype}', @ptr;

推荐阅读