【问题标题】:How to get the result sorted by "ORDINAL_POSITION" in Snowflake stored procedure?如何在雪花存储过程中获得按“ORDINAL_POSITION”排序的结果?
【发布时间】:2022-01-17 08:59:04
【问题描述】:

我编写了一个 Snowflake 存储过程,用于创建用于查看的 DDL。我使用存储过程中编写的两个查询来获取所有列,这些查询对“文本”和“日期”数据类型执行了操作。第一个查询针对“文本”,第二个查询针对“日期”数据类型。第二个查询在第一次执行时给出了动态 SQL,必须再次循环以获取列名。最后,两个查询结果(即两个查询的列名)都被追加并生成视图脚本。

CREATE OR REPLACE PROCEDURE ADMIN.generateScript (TABLENAME varchar, TABLESCHEMA varchar)
RETURNS varchar
LANGUAGE JAVASCRIPT
AS
$$
var database
database = snowflake.execute( {sqlText: "select CURRENT_DATABASE();"} );
database.next()
database_value = database.getColumnValue(1);
var TABLENAME_local =  TABLENAME ;
var TABLESCHEMA_local =  TABLESCHEMA ;
var column_count = 0
var newschema 

//Create a query by accumulating the strings and execute the query for text columns

var q1= " select CASE WHEN DATA_TYPE = 'TEXT' THEN ',nullif('||COLUMN_NAME||','''''''') AS ' ||COLUMNS.COLUMN_NAME WHEN DATA_TYPE != 'TEXT' THEN ','||COLUMN_NAME"
q1 +=   " ELSE ','||COLUMN_NAME END AS ALIAS, ORDINAL_POSITION from "+ database_value +".INFORMATION_SCHEMA.COLUMNS where  TABLE_NAME = '" 
q1 += TABLENAME_local 
q1 += "' and TABLE_SCHEMA =  '"
q1 += TABLESCHEMA_local 
q1 += "' and COLUMN_NAME not like '%_SDC_%' and DATA_TYPE not in ('TIMESTAMP_TZ','TIMESTAMP_NTZ','TIMESTAMP_LTZ', 'DATE') order by ORDINAL_POSITION;"

var rs =  snowflake.execute( {sqlText: q1} );
var return_value = "";
while (rs.next())  {
        column_count += 1;
      return_value += rs.getColumnValue(1);
       }


//Create another query by accumulating the strings and execution of this query gives dynamic SQL as result for date datatype columns

var q2 = " select COLUMN_NAME,'select '''||COLUMN_NAME||''',CASE WHEN (select count(distinct cast('||COLUMN_NAME||' AS TIME)) from "+ database_value +".'||TABLE_SCHEMA||'.'||TABLE_NAME||')>1 THEN '',convert_timezone(''''''''UTC'''''''','||COLUMN_NAME||') AS '||COLUMN_NAME||''' ELSE '','||COLUMN_NAME||'::DATE AS '||COLUMN_NAME||''' END AS STATEMENT ' "
q2 += " ,ORDINAL_POSITION from "+ database_value +".INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = '"
q2 += TABLENAME_local 
q2 += "' and TABLE_SCHEMA =  '"
q2 += TABLESCHEMA_local 
q2 += "' and COLUMN_NAME not like '%_SDC_%' and DATA_TYPE in ('TIMESTAMP_TZ','TIMESTAMP_NTZ','TIMESTAMP_LTZ', 'DATE') order by ORDINAL_POSITION;"
 
var rs1 =  snowflake.execute( {sqlText: q2} );
var rs2
while (rs1.next())  {
    rs2 =  snowflake.execute( {sqlText: rs1.getColumnValue(2)} );
    //Looping through the dynamic SQL output to get the actual columns
    while (rs2.next())  {
        column_count += 1;
      return_value += rs2.getColumnValue(2);
      }
       }
 
 //Remove the first comma in the first column
 rs1 =  snowflake.execute( {sqlText: "select RIGHT( '" + return_value + "',LEN('" + return_value + "')-1);"} );
 rs1.next()
 return_value = rs1.getColumnValue(1);

 
 //Creating view
 newschema = snowflake.execute( {sqlText: "select SUBSTRING('"+TABLESCHEMA_local+"',0,CHARINDEX('_','"+TABLESCHEMA_local+"')-1);"} );
 newschema.next()
 newschema_value = newschema.getColumnValue(1);
 query_statement =  "CREATE OR REPLACE view "+newschema_value+".vw_" +TABLENAME_local+" AS SELECT " + return_value + " from " + TABLESCHEMA_local + "."+ TABLENAME_local + " --WHERE ISDELETED = FALSE" ;
 return query_statement;
 
 
$$;

CALL ADMIN.generateScript('Table_ABC','SCHEMA_RAW')

但是生成的视图脚本没有基于 ORDINAL_POSITION 的列名,此代码首先附加第一个查询,即“文本”列,然后附加第二个查询,即“日期”列。我想生成具有基于 ORDINAL_POSITION 列的脚本,该列可以是文本和日期数据类型的组合,如下所示:

CREATE OR REPLACE view Test_View AS 
 SELECT nullif(xyz,'') AS XYZ,
 convert_timezone('UTC',CREATEDDATE) AS CREATEDDATE, 
 nullif(abc,'') AS ABC, 
 MODIFIED_DATE::DATE AS MODIFIED_DATE
 from TABLESCHEMA.TABLENAME;

TIA

【问题讨论】:

    标签: javascript sql stored-procedures snowflake-cloud-data-platform snowflake-schema


    【解决方案1】:

    直接、最简单的答案是,为了让您的ORDER BY 工作,您需要在订购前将您的记录合并在一起。

    本质上:

    SELECT column
    (
    select num_column as column, ORDINAL_POSITION
    from table
    
    union
    
    select date_column as column, ORDINAL_POSITION
    from table
    )
    order by ORDINAL_POSITION
    

    不太简单的答案是,我建议您从两个查询中提取基本列信息,然后使用 Javascript 将其组装到视图定义中并进行排序。它将使您免于在 Javascript 中的 SQL 中编写 SQL。

    从“如何在 Javascript 中删除前导逗号”和“如何在 Javascript 中对具有多列的数组进行排序”等所有内容都有一个 stackoverflow。这需要一些努力,但它绝对可以简化您的代码,并且值得学习如何在 Snowflake 程序中利用 Javascript 的强大功能。

    额外提示:如果您使用template literals,它可以显着清理您的代码,并通过避免使用q1 += " 语法使其更具可读性。

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 1970-01-01
      • 2020-09-28
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2021-10-01
      • 2021-06-22
      • 1970-01-01
      相关资源
      最近更新 更多