Ошибка компиляции SQL: идентификатор объекта схемы ‘ALL_VIEWS.TABLE_CATALOG.ВСЕ ПРОСМОТРЫ.TABLE_SCHEMA.ВСЕ ПРОСМОТРЫ.TABLE_NAME » имеет слишком много квалификаторов

#snowflake-cloud-data-platform

Вопрос:

 with all_views as (select *   from information_schema.views   where table_schema != 'INFORMATION_SCHEMA')  SELECT * FROM TABLE(get_object_references(database_name=gt;all_views.TABLE_CATALOG,  schema_name=gt;all_views.TABLE_SCHEMA,  object_name=gt;all_views.TABLE_NAME));  

Я выполнил вышеуказанный запрос в snowflake, но получил ошибку ниже.

 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=gt;'lt;db_namegt;',  schema_name=gt;'lt;schema_namegt;',  object_name=gt;'lt;view_namegt;'));  

И ниже запрос дает все представления в базе данных

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

Поэтому я подумал о том, чтобы объединить эти два запроса, чтобы предоставить мне исходные таблицы всех доступных представлений в базе данных, но вышеприведенная ошибка возникает.

Это вообще правильный путь или есть способ достичь того, чего я хочу? Спасибо.

Ответ №1:

Как упоминал Гохан, GET_OBJECT_REFERENCES может принимать только «буквальные» значения и может быть только одним объектом, а не несколькими.

Мое решение не идеально, но оно может сделать трюк, чтобы получить то, что вам нужно, используя SP для возврата строки JSON, а затем используйте RESULT_SCAN и ВЫРАВНИВАНИЕ, чтобы выровнять результат:

 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=gt;"${catalog}",  schema_name=gt;"${schema}",  object_name=gt;"${name}"  )  ); `  var sub_stmt = snowflake.createStatement( {sqlText: sub_query} );   var sub_resultset = sub_stmt.execute();    if (sub_resultset.getRowCount() lt;= 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 =gt; parse_json($1)) f;  

Комментарии:

1. Это удивительно, именно то, что я хочу, спасибо 🙂

Ответ №2:

Проблема в том, что get_object_references принимает только литеральные значения, поэтому имена ваших столбцов используются как «литеральные». Например, когда я выполняю следующий запрос, он принимает мои значения как буквальные, хотя они не заключены в одинарные кавычки.

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

Так что в вашем случае он ищет «ALL_VIEWS.TABLE_CATALOG.ВСЕ ПРОСМОТРЫ.TABLE_SCHEMA.ВСЕ ПРОСМОТРЫ.ИМЯ ТАБЛИЦЫ» в качестве имени объекта после объединения базы данных, схемы и имени объекта.

В качестве обходного пути вы можете написать процедуру JS для вызова get_object_references для каждого представления и вставить результат во временную таблицу.

Комментарии:

1. Спасибо @Gokhan, но в моей среде у базы данных не будет доступа на запись(база данных будет на стороне клиента), я не мог создавать функции или таблицы.