【问题标题】:Snowflake schema and table reference in User Defined Function arguments用户定义函数参数中的雪花模式和表引用
【发布时间】:2021-12-07 21:06:43
【问题描述】:

我正在尝试在 Snowflake 中创建一个用户定义函数 (UDF),其中参数可以将架构、表和列值作为变量接受,以便该函数可以动态调用不同的表。我尝试执行此操作并保存函数,但 Snowflake 抛出错误,指出架构名称不存在 - 它尝试使用参数名称而不是将输入到函数参数中的变量来查找架构。

这是我正在尝试做的一个示例:

CREATE OR REPLACE FUNCTION "DB_NAME"."SCHEMA_NAME"."FUNCTION_NAME"(
    SCHEMA_VAR VARCHAR,
    TABLE_VAR VARCHAR,
    COLUMN_VAR VARCHAR)
RETURNS TABLE (RETURN_COL VARCHAR)
AS
$$
SELECT COLUMN_VAR FROM "DB_NAME".SCHEMA_VAR.TABLE_VAR
$$;

【问题讨论】:

    标签: sql snowflake-cloud-data-platform


    【解决方案1】:

    您所描述的是动态 SQL,它只允许来自 stored procedure,而不是函数。

    从普通 SQL 中,您可以使用 TABLE LITERAL 从运行 SQL 的代码的角度来动态命名表,但是您也可以在代码中进行字符串操作,但这种方法使其注入安全。

    【讨论】:

    • 存储过程能否返回一个表数据集?我在 UDF 的定义中尝试了表文字,但它仍然通过将参数名称解​​释为对象的实际名称而不是变量的函数定义中的占位符而出错。
    • 是的,这就是为什么我说“来自普通 sql”而不是“TABLE LITERAL 将在 UDF 中工作”
    • 另外,为什么需要从动态表中动态获取一些行?如果这是从任务驱动的,那么该任务应该运行一个过程,该过程构建了执行您想要使用结果的工作的实际 SQL。如果您从外部工具运行 SQL,它应该将 SQL 构建成它想要的。恕我直言。我经常听到“我们想向 X 人隐藏复杂性”的论点,但通常隐藏复杂性也是一种向所有人隐藏性能的方法。
    • 目标是能够在数据库(Snowflake)本身内运行它;可能有很多不同的处理方式,因为所有类型的场景。在这种情况下,我的想法是在数据库中维护尽可能多的逻辑更简单,管理更高效,以便尽可能多的外部工具可以访问和保持一致,并尽量减少复杂逻辑的位置。已实施。
    【解决方案2】:

    老实说,即使您尝试使用UDF 实现的目标是可行的,这也是一种矫枉过正。下面考虑

    set (table_name, column_name) = ('mydb.myschema.mytable', 'mycolumn');
    
    select $column_name
    from identifier($table_name);
    

    【讨论】:

    • 也许有点矫枉过正,但我​​试图避免一遍又一遍地重写同一组 SQL,因为我想遍历一组我想在这个函数中运行的表和列。我的观点是使用函数会提高效率,因为如果我需要修改查询,我只需更新函数即可。
    • @Declan 表的列表是有限的吗?
    • 如果有限,您的意思不是无限,那么是的,表列表在运行时将是有限的,但目的是表列表可以随时间动态变化,这就是函数的原因很重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2023-01-06
    • 1970-01-01
    相关资源
    最近更新 更多