SQL 编译错误:模式对象标识符 'ALL_VIEWS.TABLE_CATALOG.ALL_VIEWS.TABLE_SCHEMA.ALL_VIEWS.TABLE_NAME' 有太多限定符

Posted

技术标签:

【中文标题】SQL 编译错误:模式对象标识符 \'ALL_VIEWS.TABLE_CATALOG.ALL_VIEWS.TABLE_SCHEMA.ALL_VIEWS.TABLE_NAME\' 有太多限定符【英文标题】:SQL compilation error: schema object identifier 'ALL_VIEWS.TABLE_CATALOG.ALL_VIEWS.TABLE_SCHEMA.ALL_VIEWS.TABLE_NAME' has too many qualifiersSQL 编译错误:模式对象标识符 'ALL_VIEWS.TABLE_CATALOG.ALL_VIEWS.TABLE_SCHEMA.ALL_VIEWS.TABLE_NAME' 有太多限定符 【发布时间】:2021-10-22 07:32:39 【问题描述】:
with all_views as (select * 
  from information_schema.views 
  where table_schema != 'INFORMATION_SCHEMA')
 SELECT * FROM TABLE(get_object_references(database_name=>all_views.TABLE_CATALOG,
                                 schema_name=>all_views.TABLE_SCHEMA,
                                 object_name=>all_views.TABLE_NAME));

我在雪花中运行了上述查询,但出现以下错误。

SQL compilation error: schema object identifier 'ALL_VIEWS.TABLE_CATALOG.ALL_VIEWS.TABLE_SCHEMA.ALL_VIEWS.TABLE_NAME' has too many qualifiers

我想做什么? 我想要数据库中所有可用视图的源表,

我尝试了什么? 下面的查询给出了给定模式和数据库下特定视图的源表。

SELECT * FROM TABLE(get_object_references(database_name=>'<db_name>',
                                 schema_name=>'<schema_name>',
                                 object_name=>'<view_name>'));

下面的查询给出了数据库下的所有视图

select * 
  from information_schema.views 
  where table_schema != 'INFORMATION_SCHEMA'

所以我想结合这两个查询来为我提供数据库中所有可用视图的源表,但抛出了上述错误。

这甚至是正确的方法还是有办法实现我想要的?谢谢。

【问题讨论】:

【参考方案1】:

正如 Gokhan 所提到的,GET_OBJECT_REFERENCES 只能接受“文字”值,并且只能是一个对象,而不是多个对象。

我的解决方案并不完美,但它可以通过使用 SP 返回 JSON 字符串,然后使用 RESULT_SCAN & FLATTEN 来展平结果,从而获得你想要的东西:

create or replace procedure get_all_object_references()
RETURNS string
LANGUAGE javascript 
AS $$
  var query = `
    select * 
    from information_schema.views 
    where table_schema != 'INFORMATION_SCHEMA'
  `
  
  var stmt = snowflake.createStatement( sqlText: query ); 
  var resultSet = stmt.execute(); 
  
  var result = [];
  
  while (resultSet.next()) 
    var catalog = resultSet.getColumnValue(1);
    var schema = resultSet.getColumnValue(2);
    var name = resultSet.getColumnValue(3);
    
    var sub_query = `
      SELECT * FROM TABLE(
        get_object_references(
          database_name=>"$catalog",
          schema_name=>"$schema",
          object_name=>"$name"
        )
      );
`
    var sub_stmt = snowflake.createStatement( sqlText: sub_query ); 
    var sub_resultset = sub_stmt.execute(); 

    if (sub_resultset.getRowCount() <= 0) 
      continue;
    

    // assume result only returns one row
    sub_resultset.next();

    var sub_result = ;
    sub_result['db_name'] = sub_resultset.DATABASE_NAME;
    sub_result['schema_name'] = sub_resultset.SCHEMA_NAME;
    sub_result['object_name'] = sub_resultset.OBJECT_NAME;
    sub_result['r_db_name'] = sub_resultset.REFERENCED_DATABASE_NAME;
    sub_result['r_schema_name'] = sub_resultset.REFERENCED_SCHEMA_NAME;
    sub_result['r_object_name'] = sub_resultset.REFERENCED_OBJECT_NAME;
    sub_result['r_object_type'] = sub_resultset.REFERENCED_OBJECT_TYPE;

    result.push(sub_result);
  

  return JSON.stringify(result);
$$;           

call get_all_object_references();

select 
  f.value:"db_name"::string       as DB_NAME, 
  f.value:"schema_name"::string   as SCHEMA_NAME,
  f.value:"object_name"::string   as OBJECT_NAME, 
  f.value:"r_db_name"::string     as REFERENCE_DB_NAME,  
  f.value:"r_schema_name"::string as REFERENCE_SCHEMA_NAME, 
  f.value:"r_object_name"::string as REFERENCE_OBJECT_NAME, 
  f.value:"r_object_type"::string as REFERENCE_OBJECT_TYPE
from table(result_scan(last_query_id())),
lateral flatten(input => parse_json($1)) f;

【讨论】:

这太棒了,正是我想要的谢谢:)【参考方案2】:

问题是 get_object_references 只接受文字值,因此您的列名被用作“文字”。例如,当我运行以下查询时,它接受我的值作为文字,尽管它们没有用单引号括起来。

SELECT * FROM TABLE(get_object_references( DATABASE_NAME => GOKHAN_DB, 
SCHEMA_NAME => PUBLIC,
OBJECT_NAME => TEST_VIEW ));

因此,在您的情况下,它在连接数据库、架构和对象名称后寻找“ALL_VIEWS.TABLE_CATALOG.ALL_VIEWS.TABLE_SCHEMA.ALL_VIEWS.TABLE_NAME”作为对象名称。

作为一种解决方法,您可以编写一个 JS 过程来为每个视图调用 get_object_references 并将结果插入到临时表中。

【讨论】:

感谢@Gokhan,但在我的环境中,数据库没有写访问权限(数据库将在客户端)我无法创建函数或表。

以上是关于SQL 编译错误:模式对象标识符 'ALL_VIEWS.TABLE_CATALOG.ALL_VIEWS.TABLE_SCHEMA.ALL_VIEWS.TABLE_NAME' 有太多限定符的主要内容,如果未能解决你的问题,请参考以下文章

存储过程 SQL 编译错误中的执行错误:Statement.execute 中的标识符“TEST3”无效

oracle 10g sql子句编译错误

SQL 错误:ORA-00904:“CNPPARMID”:标识符无效

SQL宝典

sql server的对象命名规则是啥

第五章 SQL定义表(一)