简体   繁体   English

Javascript 存储过程雪花

[英]Javascript Stored Procedure Snowflake

  1. I am working on SP which will look for table name defined in ARRAY across all database我正在研究 SP,它将在所有数据库中查找在 ARRAY 中定义的表名
  2. create view by union on same table name通过联合在同一个表名上创建视图
  3. For example for Table A if present in DB 1 and DB 2 then create view by selecting records from both the db例如,对于表 A,如果存在于 DB 1 和 DB 2 中,则通过从两个数据库中选择记录来创建视图
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();  

Note:- code provided above is creating view by selecting data from one db only, ideally it should select from both db's.注意:- 上面提供的代码仅通过从一个数据库中选择数据来创建视图,理想情况下,它应该从两个数据库中选择 select。 Any help will be appreciated!!任何帮助将不胜感激!! I am new to JS SP我是 JS SP 的新手

SQL is expressive enough to achieve it(no loops are necessary). SQL 的表现力足以实现它(不需要循环)。

Using Snowflake Scripting and single query based on ACCOUNT_USAGE.TABLES (the account_usage views have latency):使用雪花脚本和基于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:称呼:

CALL PROC1();

Output: 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;

Inline query - the clue of this solution is to generate CREATE VIEW based on metadata table:内联查询 - 这个解决方案的线索是根据元数据表生成CREATE VIEW

inner aggregate LISTAGG() - (multiple tables per create view with withe the same table name)内部聚合 LISTAGG() -(每个创建视图具有相同表名的多个表)

outer analytical LISTAGG() OVER() - combine multiple create view into single output inside begin... end block(required by execute immediate )外部分析 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;

Sample input:样本输入:

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;

Test of created view:创建视图的测试:

SELECT *
FROM TERRA_DB.TERRA_SCHEMA.ALL_STAGE_TABLE;

Output: Output:

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM