如何在没有动态 sql 的情况下将架构参数传递给过程
How to pass schema parameter to a procedure without dynamic sql
我试图在不使用动态 SQL.
的情况下将参数化模式名称(或 table 名称)传递到过程中
该过程目前使用动态进行,但我的任务是尽可能多地从我们的系统中删除动态 sql。从研究中我知道 DynamicSQL 是常见的答案,并且历史上没有办法做到这一点,但随着时间的推移事情会发生变化所以我看看是否有人找到了更好的解决方案。
我试过:
- 创建动态 user/login/schema,然后为用户设置默认架构并包括 EXECUTE AS 代码
- 不起作用,因为过程架构优先于 select 查询 - 不考虑用户默认架构
- 创建同义词
- 不起作用,因为同义词不能dynamic/session具体
我目前无法在不完全重新设计数据库的情况下改进现有的内容 - 这不是我可以轻易承担的任务。
任何其他options/suggestions感激不尽。
非常感谢@Sepupic,虽然最终的答案不是他的,但它帮助我走上了我需要的道路。他对致谢的评论+1。
我最终使用的解决方案:
用于将存储过程从架构 "template" 复制到架构 @SessionID
的存储过程
CREATE PROC [dbo].[usp_CopySproc]
@SessionID NVARCHAR(255)
, @ProcName NVARCHAR(255)
AS
BEGIN
DECLARE @strSQL AS NVARCHAR(MAX)
DECLARE @FullProcName AS NVARCHAR(MAX)
SET @FullProcName = @SessionID + '.' + @ProcName
IF OBJECT_ID(@FullProcName) IS NULL
BEGIN
PRINT 'Creating ' + @FullProcName
SET @strSQL = OBJECT_DEFINITION(OBJECT_ID('template.' + @ProcName))
SET @strSQL = STUFF(@strSQL, PATINDEX('%template%', @strSQL), 8, @SessionID)
EXEC (@strSQL)
END
ELSE
PRINT @FullProcName + ' already exists'
END
我在会话启动时设置了一个架构,准备好包含过程和会话数据。然后使用如下命令复制过程:
DECLARE @strSQL NVARCHAR(MAX)
, @SessionID NVARCHAR(255) = 'mySession'
EXEC dbo.usp_CopySproc @SessionID , 'usp_RefreshPriceSummary'
SET @strSQL = @SessionID + '.usp_RefreshPriceSummary'
EXEC @strSQL @SessionID
然后,我复制的过程可以从会话模式中的 table 中 select,而无需限定它们的模式。
终于在会话中 close/cleanup 我浏览了对象 table 删除了具有该架构 ID 的任何内容。
我试图在不使用动态 SQL.
的情况下将参数化模式名称(或 table 名称)传递到过程中该过程目前使用动态进行,但我的任务是尽可能多地从我们的系统中删除动态 sql。从研究中我知道 DynamicSQL 是常见的答案,并且历史上没有办法做到这一点,但随着时间的推移事情会发生变化所以我看看是否有人找到了更好的解决方案。
我试过:
- 创建动态 user/login/schema,然后为用户设置默认架构并包括 EXECUTE AS 代码
- 不起作用,因为过程架构优先于 select 查询 - 不考虑用户默认架构
- 创建同义词
- 不起作用,因为同义词不能dynamic/session具体
我目前无法在不完全重新设计数据库的情况下改进现有的内容 - 这不是我可以轻易承担的任务。
任何其他options/suggestions感激不尽。
非常感谢@Sepupic,虽然最终的答案不是他的,但它帮助我走上了我需要的道路。他对致谢的评论+1。
我最终使用的解决方案:
用于将存储过程从架构 "template" 复制到架构 @SessionID
的存储过程CREATE PROC [dbo].[usp_CopySproc]
@SessionID NVARCHAR(255)
, @ProcName NVARCHAR(255)
AS
BEGIN
DECLARE @strSQL AS NVARCHAR(MAX)
DECLARE @FullProcName AS NVARCHAR(MAX)
SET @FullProcName = @SessionID + '.' + @ProcName
IF OBJECT_ID(@FullProcName) IS NULL
BEGIN
PRINT 'Creating ' + @FullProcName
SET @strSQL = OBJECT_DEFINITION(OBJECT_ID('template.' + @ProcName))
SET @strSQL = STUFF(@strSQL, PATINDEX('%template%', @strSQL), 8, @SessionID)
EXEC (@strSQL)
END
ELSE
PRINT @FullProcName + ' already exists'
END
我在会话启动时设置了一个架构,准备好包含过程和会话数据。然后使用如下命令复制过程:
DECLARE @strSQL NVARCHAR(MAX)
, @SessionID NVARCHAR(255) = 'mySession'
EXEC dbo.usp_CopySproc @SessionID , 'usp_RefreshPriceSummary'
SET @strSQL = @SessionID + '.usp_RefreshPriceSummary'
EXEC @strSQL @SessionID
然后,我复制的过程可以从会话模式中的 table 中 select,而无需限定它们的模式。
终于在会话中 close/cleanup 我浏览了对象 table 删除了具有该架构 ID 的任何内容。