You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

sp_describe_first_result_set遇REVERT失败,如何获取调用方数据库主体?

解决sp_describe_first_result_set遇到REVERT无法获取元数据的问题

方案1:将调用方用户获取逻辑封装到单独存储过程

把需要切换到CALLER上下文的逻辑抽离到独立的、带有WITH EXECUTE AS CALLER的存储过程中,主存储过程无需自行执行EXECUTE AS和REVERT,从而避开元数据检测对REVERT的限制。

示例代码:

-- 封装获取调用方用户的存储过程
CREATE OR ALTER PROCEDURE sp_GetCallerUserName
WITH EXECUTE AS CALLER
AS
BEGIN
    SELECT USER_NAME() AS CallerUserName;
END
GO

-- 主存储过程
CREATE OR ALTER PROCEDURE spTest
WITH EXECUTE AS OWNER
AS
BEGIN
    DECLARE @name sysname;
    
    -- 调用封装的存储过程获取调用方用户
    SELECT @name = CallerUserName FROM sp_GetCallerUserName();

    SELECT 'Hello ' + @name AS Msg;
END
GO

-- 现在可以正常获取元数据
EXEC sp_describe_first_result_set N'EXEC spTest', NULL, 0

方案2:条件执行REVERT(依赖内部函数)

利用SQL Server内部函数sys.fn_MSis_meta_function_call()判断当前是否处于元数据检测上下文,仅在非检测时执行REVERT,避免元数据分析时触发错误。

示例代码:

CREATE OR ALTER PROCEDURE spTest
WITH EXECUTE AS OWNER
AS
BEGIN
    DECLARE @name sysname;
    
    EXECUTE AS CALLER;
    SELECT @name = USER_NAME();
    
    -- 仅非元数据检测场景执行REVERT
    IF NOT sys.fn_MSis_meta_function_call()
    BEGIN
        REVERT;
    END

    SELECT 'Hello ' + @name AS Msg;
END
GO

EXEC sp_describe_first_result_set N'EXEC spTest', NULL, 0

方案3:直接通过系统视图获取调用方数据库用户

无需上下文切换,通过关联系统视图从登录名映射到当前数据库的用户主体:

CREATE OR ALTER PROCEDURE spTest
WITH EXECUTE AS OWNER
AS
BEGIN
    DECLARE @name sysname;
    
    -- 通过登录名关联当前数据库用户
    SELECT @name = dp.name
    FROM sys.server_principals sp
    JOIN sys.database_principals dp ON sp.sid = dp.sid
    WHERE sp.name = ORIGINAL_LOGIN();

    SELECT 'Hello ' + @name AS Msg;
END
GO

EXEC sp_describe_first_result_set N'EXEC spTest', NULL, 0

注意:此方法依赖登录名与数据库用户的SID匹配,若调用方登录名未在当前数据库映射对应用户会返回NULL,需额外处理边界情况。

内容的提问来源于stack exchange,提问作者Ola Berntsson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 20:56:35