Redshift UDF 逻辑问题

Posted

技术标签:

【中文标题】Redshift UDF 逻辑问题【英文标题】:Redshift UDF logical issue 【发布时间】:2019-12-26 08:03:17 【问题描述】:

我正在尝试编写一个 redshift udf 来验证时间戳。但是,它总是返回 false。有人能解释一下原因吗?

create or replace function f_Is_timestamp_sql(VARCHAR(20000))
  returns timestamp  
  STABLE
as $$
       select $1::timestamp as a;
$$ language sql;

create or replace function f_Is_timestamp(val VARCHAR(20000))
  returns bool
IMMUTABLE 
as $$
    try:
       (f_Is_timestamp_sql(val));  
    except:
       return (1==2);
    else:
      return 1==1;
$$ language plpythonu;

select f_Is_timestamp('2019-10-09')

【问题讨论】:

能否请您说明您打算如何使用此功能?您是否将字符串传递给函数并且想知道它是否成功转换为TIMESTAMP?您的示例是DATE,而不是TIMESTAMP 是的,我打算检查是否可以将传递的字符串转换为时间戳。虽然它是一个日期,但它仍然可以转换为时间戳,不是吗?即使对于此选择 f_Is_timestamp('2019-10-09 00:00:00'),这也会返回 false 我想知道您是否可以简单地执行return ($1::timestamp)::varchar == $1 之类的操作?这将检查它在转换为时间戳并返回字符串时是否是相同的值。 我理解您尝试使用的逻辑。但是,我想编写一个通用函数,可以从任何格式转换为时间戳。 “选择'01-jANUARY-2019 01:01:01'::timestamp”这适用于红移。但按照你的逻辑,它是行不通的。我说的对吗? 也许检查$1::timestamp 导致一个非空的时间戳值?您确定无效值会导致 UDF 中的异常吗? 【参考方案1】:

通读 AWS 文档后,我发现一个 UDF 无法引用另一个 UDF 的内容。 https://docs.aws.amazon.com/redshift/latest/dg/udf-python-language-support.html 因此,我的函数总是抛出异常。我想出了另一种使用 python 库完成此任务的方法

dateutil.parser

下面的工作函数。

create or replace function f_Is_timestamp(val VARCHAR(20000))
  returns bool
IMMUTABLE 
as $$
    from dateutil.parser import parse;
    try:
        parse(val,ignoretz=True);
    except:
        return 1==2;
    else:
        return 1==1;
$$ language plpythonu;

【讨论】:

在Python中,你可以return Truereturn False

以上是关于Redshift UDF 逻辑问题的主要内容,如果未能解决你的问题,请参考以下文章

AWS Redshift UDF 错误

redshift 更改 udf 更改所有者

Redshift:不能在 UDF 中使用聚合函数?

如何在 Redshift(亚马逊)中更新 UDF?

我们应该在 Redshift 的存储过程中使用 udf

Redshift UDF 兼容性问题