【问题标题】:Microsoft Azure Mobile Service Javascript Custom API executes db stored procedure permission issueMicrosoft Azure 移动服务 Javascript 自定义 API 执行 db 存储过程权限问题
【发布时间】:2015-02-10 17:02:44
【问题描述】:

我有如下自定义的HTTP GET api函数,权限对所有人都允许:

exports.get = function(request, response) {
    var mssql = request.service.mssql;
    mssql.query('exec dbo.spTest',
    {
        success: function (result){
            request.respond(statusCodes.OK, result);
        },
        error: function(err) {
            console.log("error is: " + err);
        }        
    })
};

这是我的存储过程,很简单的一个:

Create PROCEDURE dbo.[spTest]
AS
BEGIN
    DECLARE @tmpTest Table(BrandName VARCHAR(255))
    INSERT INTO @tmpTest
        SELECT BrandName FROM dbo.tblBrands WHERE [_key]=105
    SELECT BrandName FROM @tmpTest  
END

如果我在数据库上运行它,它就可以工作。 [我以管理员身份登录数据库] 但是自定义API无法执行这个SP,即使没有任何错误信息,结果变量是一个空数组:“[]”。

然后我把我的SP改成

Create PROCEDURE dbo.[spTest]
AS
BEGIN
        SELECT BrandName FROM dbo.tblBrands WHERE [_key]=105
END

它直接从表中选择而不是使用表变量,它可以工作。

因为自定义 API 将 DB 连接到自己的用户帐户,而不是 admin 用户,我猜这个 API 帐户没有足够的权限来声明表变量。我也试过临时表,它也不起作用。

有人知道授予自定义 API 用户权限的解决方案吗?谢谢

更新

忘记数据库端,即使以下脚本在 API 中也不起作用:

exports.get = function(request, response) {
    var mssql = request.service.mssql;

    mssql.query('declare @ttt Table(NAME VARCHAR(255)); insert into @ttt values (\'Jack\'); select * from @ttt;',
    {
      success: function (result){
        console.log("success");
        request.respond(statusCodes.OK, result);
    },
      error: function(err) {
        console.log("error is: " + err);
    }        
})

};

声明一个表变量或临时表不会引发错误,但是对它们的任何操作[选择、插入、更新]都会得到异常并且请求返回只是一个空数组[]。在日志中,只记录了“成功”。请帮忙

【问题讨论】:

    标签: api azure-mobile-services


    【解决方案1】:

    已编辑:
    啊,这与 Temp 表有关 - 您可以在 sp 的开头使用 SET NOCOUNT ON - 这可以防止在 temp 表操作仍在发生时发回 done_in_proc 消息。 https://msdn.microsoft.com/en-us/library/ms189837.aspx

    您的新 SP 如下所示:

    Create PROCEDURE dbo.[spTest]
    AS
    BEGIN
        -- Suppress RowCount done_in_proc messages emitted from insert
        SET NOCOUNT ON
        DECLARE @tmpTest Table(BrandName VARCHAR(255))
        INSERT INTO @tmpTest
            SELECT BrandName FROM dbo.tblBrands WHERE [_key]=105
        -- Enable rowcount done_in_proc messages going forward and enabling rowcount meta
        SET NOCOUNT OFF
        SELECT BrandName FROM @tmpTest  
    END
    

    原始回复:
    很难说没有访问数据库,但这可能是模式权限问题吗?通常,会使用您的移动服务名称创建一个新架构。 AMS 创建的服务帐户没有 [dbo] 架构的权限。您可以授予架构权限(这不是一个好的安全做法,或者将 sp 放在由 AMS 创建的架构下。我能够重现您发出的类似问题:

    EXECUTE AS user = 'ivZJMJrfRDLogin_MyAMSUser';
    select * from dbo.TodoItem;
    

    返回:

    The SELECT permission was denied on the object 'TodoItem', database 'MyAMS_db', schema 'dbo'.
    

    (仅供参考 - 我使用一些名称来混淆我的服务器/数据库/用户名)。

    【讨论】:

    • 感谢您的回答,我将 AMS 用户添加为 'db_owner' 的成员,并将其授予 dbo 模式。它不起作用。实际上没有任何与权限相关的错误消息。我还做了一些其他的快速测试,请看看我更新的问题
    • 你说得对,我应该在 SP 中设置 NOCOUNT ON。我不知道自定义 API 会捕获那些 done_in_Proc 消息以及结果集。感谢您回答我的问题。
    • 您知道自定义 API 何时捕获那些 done_in_Proc 消息,如何读取结果中受影响的行数?谢谢
    • 您可以将 SET NOCOUNT OFF 语句放在您实际要为其返回结果的 select 语句之前。实际上,我会根据该建议编辑我的评论。
    【解决方案2】:

    我从网站的另一个帖子中找到了我的问题的解释:/azure-mobile-services-custom-api-update-ouput-followed-by-select-returns-empty/

    简单来说,查询返回的结果有两种,一种是对表变量的插入操作,另一种是对表变量的选择操作。那么自定义 API 只是从插入操作中获得第一个空返回。解决方法请参考carlosfigueira的说明。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      相关资源
      最近更新 更多