J.D*_*.D. 3 sql-server stored-procedures dynamic-sql sql-server-2008-r2
奇怪的问题?...也许,但我有需要。:)
我有一个存储过程,我想在任何数据库中普遍使用。存储过程生成一些动态 SQL,然后在作为此过程中的参数之一传入的数据库中执行该 SQL。
但是我想让数据库参数成为可选的,并且当没有传入数据库名称时,我希望动态 SQL 在调用过程本身的同一个数据库中执行。(请记住,此过程可以跨数据库执行,而不是在该过程本身所在的同一数据库中执行。)
您可以通过动态构建[database].sys.sp_executesql
命令来轻松告诉特定数据库中的动态 SQL 执行:
USE your_database;
GO
CREATE PROCEDURE dbo.DatabaseNameOptional
@db sysname = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE @sql nvarchar(max) = N'SELECT DB_NAME(); /* other stuff */'
DECLARE @exec nvarchar(770) = COALESCE(@db, DB_NAME())
+ N'.sys.sp_executesql';
-- alternatively, just leave DB_NAME() out of it:
--DECLARE @exec nvarchar(770) = COALESCE(@db, N'')
-- + N'sys.sp_executesql';
EXEC @exec @sql;
END
GO
Run Code Online (Sandbox Code Playgroud)
试试看:
USE your_database;
GO
EXEC dbo.DatabaseNameOptional;
GO -- output = your_database
EXEC dbo.DatabaseNameOptional @db = N'master';
GO -- output = master
USE tempdb;
GO
EXEC your_database.dbo.DatabaseNameOptional;
GO -- output = your_database
EXEC your_database.dbo.DatabaseNameOptional @db = N'master';
GO -- output = master
Run Code Online (Sandbox Code Playgroud)
但是,在过程的执行上下文中,不,我认为没有任何方法可以确定调用源自何处(或在该上下文中运行)。这就是在 master 中使用系统标记过程的好处 - 如果这是您想要的功能,您需要确定“将对象放入 master”是否比“没有得到我想要的”更令人讨厌。