【发布时间】: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