[英]Javascript Stored Procedure Snowflake
create or replace procedure PROC_1()
returns VARCHAR -- return final create statement
language javascript
as
$$
//given two db for testing
var get_databases_stmt = "SELECT DATABASE_NAME FROM SNOWFLAKE.INFORMATION_SCHEMA.DATABASES WHERE DATABASE_NAME='TERRA_DB' OR DATABASE_NAME='TERRA_DB_2'"
var get_databases_stmt = snowflake.createStatement({sqlText:get_databases_stmt });
var databases = get_databases_stmt.execute();
var row_count = get_databases_stmt.getRowCount();
var rows_iterated = 0;
//table on which view will be created
var results_table=['STAGE_TABLE','JS_TEST_TABLE];
var results_db=[];
while (databases.next()) {
var database_name = databases.getColumnValue(1);
//rows_iterated += 1;
for (let j = 0; j < results_table.length; j++){
var stmt="CREATE OR REPLACE VIEW TERRA_DB.TERRA_SCHEMA.ALL_"+results_table[j]+" AS \n";
stmt += "SELECT * FROM "+database_name+".TERRA_SCHEMA." + results_table[j]
if (rows_iterated < row_count){
stmt += " UNION ALL";
}
++rows_iterated;
}
}
//var sql = snowflake.createStatement({sqlText:stmt});
//var res =sql.execute();
return stmt;
$$;
call PROC_1();
注意:- 上面提供的代碼僅通過從一個數據庫中選擇數據來創建視圖,理想情況下,它應該從兩個數據庫中選擇 select。 任何幫助將不勝感激!! 我是 JS SP 的新手
SQL 的表現力足以實現它(不需要循環)。
使用雪花腳本和基於ACCOUNT_USAGE.TABLES的單個查詢(account_usage 視圖有延遲):
CREATE OR REPLACE PROCEDURE PROC1()
RETURNS TEXT
LANGUAGE SQL
AS
DECLARE
sql TEXT;
schema_name TEXT := 'TERRA_SCHEMA';
database_names ARRAY := ARRAY_CONSTRUCT('TERRA_DB', 'TERRA_DB_2');
table_names ARRAY := ARRAY_CONSTRUCT('STAGE_TABLE','JS_TEST_TABLE');
BEGIN
SELECT
CONCAT('BEGIN',
LISTAGG(CONCAT('\nCREATE OR REPLACE VIEW TERRA_DB.TERRA_SCHEMA.ALL_'
, T.TABLE_NAME, ' AS\n',
LISTAGG(CONCAT('SELECT * FROM ', T.TABLE_CATALOG, '.'
, T.TABLE_SCHEMA ,'.', T.TABLE_NAME), ' UNION ALL\n')
, ';')) OVER(),'\nEND;') AS query
INTO sql
FROM SNOWFLAKE.ACCOUNT_USAGE.TABLES AS T
WHERE T.DELETED IS NULL
AND T.TABLE_SCHEMA ILIKE :schema_name
AND T.TABLE_NAME IN (SELECT VALUE FROM TABLE(FLATTEN(INPUT=>:table_names)))
AND T.TABLE_CATALOG IN (SELECT VALUE FROM TABLE(FLATTEN(INPUT=>:database_names)))
GROUP BY T.TABLE_NAME
LIMIT 1;
EXECUTE IMMEDIATE sql;
RETURN sql;
END;
稱呼:
CALL PROC1();
Output:
BEGIN
CREATE OR REPLACE VIEW TERRA_DB.TERRA_SCHEMA.ALL_STAGE_TABLE AS
SELECT * FROM TERRA_DB.TERRA_SCHEMA.STAGE_TABLE UNION ALL
SELECT * FROM TERRA_DB_2.TERRA_SCHEMA.STAGE_TABLE;
CREATE OR REPLACE VIEW TERRA_DB.TERRA_SCHEMA.ALL_JS_TEST_TABLE AS
SELECT * FROM TERRA_DB.TERRA_SCHEMA.JS_TEST_TABLE;
END;
內聯查詢 - 這個解決方案的線索是根據元數據表生成CREATE VIEW
:
內部聚合 LISTAGG() -(每個創建視圖具有相同表名的多個表)
外部分析 LISTAGG() OVER() - 將多個創建視圖組合到單個 output 內begin... end
塊(需要execute immediate
)
SELECT
CONCAT('BEGIN',
LISTAGG(CONCAT('\nCREATE OR REPLACE VIEW TERRA_DB.TERRA_SCHEMA.ALL_'
, T.TABLE_NAME, ' AS\n',
LISTAGG(CONCAT('SELECT * FROM ', T.TABLE_CATALOG, '.'
, T.TABLE_SCHEMA ,'.', T.TABLE_NAME), ' UNION ALL\n')
, ';')) OVER(),'\nEND;') AS query
FROM SNOWFLAKE.ACCOUNT_USAGE.TABLES AS T
WHERE T.DELETED IS NULL
AND T.TABLE_SCHEMA ILIKE 'TERRA_SCHEMA'
AND T.TABLE_NAME IN (SELECT VALUE FROM TABLE(FLATTEN(INPUT=>
ARRAY_CONSTRUCT('STAGE_TABLE','JS_TEST_TABLE'))))
AND T.TABLE_CATALOG IN (SELECT VALUE FROM TABLE(FLATTEN(INPUT=>
ARRAY_CONSTRUCT('TERRA_DB', 'TERRA_DB_2'))))
GROUP BY T.TABLE_NAME
LIMIT 1;
樣本輸入:
CREATE OR REPLACE DATABASE TERRA_DB;
CREATE OR REPLACE SCHEMA TERRA_SCHEMA;
CREATE OR REPLACE TABLE STAGE_TABLE(col TEXT, col2 INT) AS
SELECT 'TERRA_DB.TERRA_ALL.STAGE_TABLE', 1;
CREATE OR REPLACE TABLE TERRA_SCHEMA.JS_TEST_TABLE(col TEXT, col2 INT) AS
SELECT 'TERRA_DB.TERRA_ALL.JS_TEST_TABLE', 1;
CREATE OR REPLACE DATABASE TERRA_DB_2;
CREATE OR REPLACE SCHEMA TERRA_SCHEMA;
CREATE OR REPLACE TABLE TERRA_SCHEMA.STAGE_TABLE(col TEXT, col2 INT) AS
SELECT 'TERRA_DB_2.TERRA_ALL.STAGE_TABLE', 2;
創建視圖的測試:
SELECT *
FROM TERRA_DB.TERRA_SCHEMA.ALL_STAGE_TABLE;
Output:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.