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”无效