Snowflake DB UDF 可以执行 SQL 命令吗?
Posted
技术标签:
【中文标题】Snowflake DB UDF 可以执行 SQL 命令吗?【英文标题】:Can Snowflake DB UDF's execute SQL commands? 【发布时间】:2018-11-02 15:15:36 【问题描述】:我在 Snowflake 中有一个要求,我必须生成一些 SQL,然后执行它来创建一个新表。
我已经通过创建UDF成功生成了create table语句(目前是硬编码)
CREATE OR REPLACE FUNCTION COOL_CARGO.test()
RETURNS STRING
AS
$$
SELECT substr(regexp_replace(GET_DDL('TABLE', 'COOL_CARGO.DIM_BRANCH'),('DIM_BRANCH'),'COOL_CARGO.DIM_BRANCH_ERR'), 0, LENGTH(regexp_replace(GET_DDL('TABLE', 'COOL_CARGO.DIM_BRANCH'),('DIM_BRANCH'),'COOL_CARGO.DIM_BRANCH_ERR')) -2)||','||' etl_err_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
etl_id_run int DEFAULT NULL,
etl_err_noe int DEFAULT NULL,
etl_err_desc varchar(512) DEFAULT NULL,
etl_err_col varchar(256) DEFAULT NULL,
etl_err_cod varchar(256) DEFAULT NULL'||');'
$$
;
这会输出以下内容
create or replace TABLE COOL_CARGO.DIM_BRANCH_ERR (
TK_BRANCH NUMBER(38,0),
GB_BRANCH_CODE VARCHAR(256),
GB_BRANCH_NAME VARCHAR(256),
GB_BRANCH_CITY VARCHAR(256),
GB_BRANCH_STATE VARCHAR(256),
BG_BRANCH_HOME_PORT VARCHAR(256),
BG_BRANCH_COUNTRY_CODE VARCHAR(256),
BG_BRANCH_COUNTRY_NAME VARCHAR(256)
, etl_err_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
etl_id_run int DEFAULT NULL,
etl_err_noe int DEFAULT NULL,
etl_err_desc varchar(512) DEFAULT NULL,
etl_err_col varchar(256) DEFAULT NULL,
etl_err_cod varchar(256) DEFAULT NULL);
我现在需要创建一个 UDF 来执行这个 create table 语句,但由于它似乎只返回字符串之类的东西,我无法通过例如从另一个函数调用它来执行它。
CREATE OR REPLACE FUNCTION COOL_CARGO.run_test()
RETURNS string
AS
$$
COOL_CARGO.test()
$$
;
然后我尝试运行函数来创建表
select COOL_CARGO.run_test();
我不知道我想要的能不能做到,如果不可能,我会很生气......
这可以在 Snowflake DB 中完成吗?
【问题讨论】:
Snowflake UDF 不支持调用其他类似的函数,也不支持类似 eval 的功能。你需要存储过程。他们来了! 谢谢,我担心是这样的:(我想你不知道存储过程什么时候到来? Snowflake 社区论坛是最好的提问场所。你甚至可以及早获得它:) 【参考方案1】:您可以通过 2019 推出的 Snowflake 的新 Stored Procedures feature 来实现这一点。它允许您构建任意 SQL 字符串并在 SQL 或 javascript 中执行。
您现有的方法可以很容易地适应存储过程(下面的示例是说明性的,尚未经过专门测试):
create or replace procedure test()
returns null
language javascript
as
$$
var orig_ddl_qry = "SELECT GET_DDL('TABLE', 'COOL_CARGO.DIM_BRANCH')";
var get_ddl_stmt = snowflake.createStatement(
sqlText: orig_ddl_qry
);
var get_ddl_res = get_ddl_stmt.execute();
get_ddl_res.next();
var orig_ddl_str = res.getColumnValue(1);
var replaced_ddl_open = orig_ddl_str.replace("DIM_BRANCH", "COOL_CARGO.DIM_BRANCH_ERR").slice(0, -1);
var new_ddl = replaced_ddl_open + ", etl_err_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, etl_id_run int DEFAULT NULL, etl_err_noe int DEFAULT NULL, etl_err_desc varchar(512) DEFAULT NULL, etl_err_col varchar(256) DEFAULT NULL, etl_err_cod varchar(256) DEFAULT NULL);";
var create_stmt = snowflake.createStatement(
sqlText: new_ddl
);
var create_ddl_res = create_stmt.execute();
$$
;
CALL test();
【讨论】:
以上是关于Snowflake DB UDF 可以执行 SQL 命令吗?的主要内容,如果未能解决你的问题,请参考以下文章
Snowflake 支持 Java UDF 的 JDK 版本是啥?