如何将schema参数传递给没有动态sql的过程

时间:2017-11-23 10:30:02

标签: sql-server stored-procedures schema dynamic-sql

我试图在不使用动态SQL的情况下将参数化模式名称(或表名称)传递给过程。

该过程目前使用动态,但我的任务是尽可能从系统中删除尽可能多的动态sql。从研究中我知道DynamicSQL是常见的答案,而且历史上一直没有办法做到这一点,但随着时间的推移,事情会发生变化,所以我看到是否有人找到了更好的解决方案。

我试过了:

  • 创建动态用户/登录/架构,然后在用户上设置默认架构并包括EXECUTE AS代码
    • 不起作用,因为过程模式优先于选择查询 - 不考虑用户默认模式
  • 创建同义词
    • 不起作用,因为同义词不能动态/特定于会话

我目前无法在不完全重新设计数据库的情况下改进存在的东西 - 这不是我会轻易采取的任务。

感激地收到任何其他选项/建议。

1 个答案:

答案 0 :(得分:0)

非常感谢@Sepupic,虽然最后的答案不是他的,但它帮助我走上了我需要的道路。他对信用评论的评价为+ 1。

解决方案我终于使用了:

将存储过程从模式“模板”复制到模式@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

然后,我复制的过程可以从会话模式中的表中进行选择,而无需限定其模式。

最后在会话关闭/清理时,我浏览了对象表,删除了具有该模式ID的任何内容。