如何在 Snowflake 存储过程中获取按 "ORDINAL_POSITION" 排序的结果?

How to get the result sorted by "ORDINAL_POSITION" in Snowflake stored procedure?

我已经编写了一个 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

最直接、最简单的答案是,为了让您的 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 到 assemble 将其放入视图定义并进行排序。这将使您免于在 Javascript.

内的 SQL 内编写 SQL

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

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