【问题标题】:Snowflake: Execution error in store procedure : SQL compilation error: Object does not exist or not authorized. At Statement.execute雪花:存储过程中的执行错误:SQL 编译错误:对象不存在或未授权。在 Statement.execute
【发布时间】:2020-08-06 05:30:15
【问题描述】:

我完全被雪花系统的权限模型弄糊涂了。我创建了一个数据库,在该数据库中创建了一个存储过程,并尝试使用 SYSADMIN 角色中的同一用户调用该存储过程。我收到错误“存储过程中的执行错误:SQL 编译错误:对象不存在或未授权。在 Statement.execute”

我什至不知道从哪里开始。我的用户如何无权访问该用户创建的表?

【问题讨论】:

  • 您是否创建了 sp 和错误所指的表?
  • 是的。我相信我已经使用 SYSADMIN 角色下的同一用户在此 Snowflake 帐户中创建了所有内容。
  • show tables能不能看表
  • 是的,表格出现了,它的所有者是 SYSADMIN。这对我来说毫无意义。

标签: snowflake-cloud-data-platform


【解决方案1】:

有两件事要检查。

  1. 用双引号将表名括起来。检查案例。
  2. GRANT SELECT ON SCHEMA "SCHEMA_NAME" 中的所有表以 ROLE PUBLIC;

【讨论】:

    【解决方案2】:

    可能不是表格区分大小写的问题,但可能与你创建的存储过程(Function)的权限有关。

    如下更改您的代码可能会成功。

    EXECUTE AS OWNER -- Present
    EXECUTE AS CALLER -- Change
    

    要了解更多关于存储过程的所有者权利和调用者权利,请点击以下链接。 https://docs.snowflake.com/en/sql-reference/stored-procedures-rights.html

    【讨论】:

      【解决方案3】:

      最终我找不到存储过程不起作用的原因。我最终放弃了表格并使用全大写名称重新创建它。之后,我能够毫无问题地运行存储过程。

      我不清楚修复是使用 UCASE 名称创建表还是使用 USER ROLE SYSADMIN 命令重新创建它。

      【讨论】:

        【解决方案4】:

        存储过程返回包含单列的单行;它不是为返回结果集而设计的。但是,如果您的结果集足够小以适合 VARIANT 或 ARRAY 类型的单个值,您可以使用一些额外的代码从存储过程返回结果集 - here

        希望这会有所帮助!

        它适用于删除语句!示例如下:

        use role sysadmin;
        create or replace database DATA_IMPORTS_SO;
        create or replace table ProductMaster_SO (id integer, name varchar);
        insert into ProductMaster_SO values (1,'stackoverflow');
        insert into ProductMaster_SO values (2,'stackoverflow');
        select count(*) FROM DATA_IMPORTS_SO.PUBLIC.ProductMaster_SO;--2 rows
        create or replace procedure Clenup_DI_Products()
        returns string not null
        language javascript
        EXECUTE AS OWNER
        as
        $$
        var sql_command = 
             "delete FROM DATA_IMPORTS_SO.PUBLIC.ProductMaster_SO";
            try {
                snowflake.execute (
                    {sqlText: sql_command}
                    );
                return "Succeeded.";   // Return a success/error indicator.
                }
            catch (err)  {
                return "Failed: " + err;   // Return a success/error indicator.
                }
        $$;
        
        call Clenup_DI_Products();
        select count(*) FROM DATA_IMPORTS_SO.PUBLIC.ProductMaster_SO;--0 rows
        

        【讨论】:

        • 我实际上只是让过程返回原始 Select 语句,而不是结果集。我在访问表本身时遇到错误。在深入研究此清理过程的真正目的之前,我试图让这个简单的选择起作用。
        • 我没有授予用户对表或过程的任何权限。并且能够使用由同一用户 (SYSADMIN) 创建的表执行 SP。您可以试一下执行上面的代码,如果您遇到错误,请告诉我们?
        • 这绝对有效。我可以毫无问题地运行新创建的存储过程。
        • 我仍然无法弄清楚为什么现有的 proc/table 不起作用。最好我能说一切都归 SYSADMIN 所有,尽管我看不到任何地方可以看到谁拥有该 proc。我什至放弃了 proc,并使用角色 sysadmin 再次创建它;命令。仍然无法访问该表。
        【解决方案5】:

        检查您所指对象名称的大小写。例如,如果您创建了用双引号括起来的表,则它区分大小写。 Snowflake 自动将不带引号的标识符转换为大写。

        例子:

            CREATE TABLE test1 (
            test nvarchar)
        
            CREATE TABLE "teSt2" (
            test nvarchar)
        
           -- This works
            select * from test1
        
           -- This doesn't work because the table was created wrapped in double quotes and with a capital S in the name
            select * from test2
        
           -- This doesn't work either because it will convert to UPPER
            select * from teSt2
        
           -- This works
            select * from "teSt2"
        

        【讨论】:

        • 我真的希望这就是答案!唉,事实并非如此。我正在用第二个屏幕截图编辑原始帖子。
        猜你喜欢
        • 2022-11-15
        • 1970-01-01
        • 1970-01-01
        • 2020-03-16
        • 1970-01-01
        • 2021-10-01
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多