给出文件名:
XXXX / 2013-02 / CSV / Sales_1302040000-1302050000.zip
有人可以解释为什么regexp_matches在此函数中返回null:
CREATE OR REPLACE FUNCTION get_import_batch_date(filename text)
RETURNS DATE AS
$BODY$
DECLARE
matches text[];
result date;
BEGIN
matches := regexp_matches(filename, E'Sales_(\\d{2})(\\d{2})(\\d{2})');
IF matches IS NOT NULL THEN
result := format('%s-%s-%s', 2000 + matches[1]::int, matches[2], matches[3])::DATE;
RETURN result;
END IF;
RAISE WARNING 'Unable to determine batch date from %', filename;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE;
但是,可以使用以下匿名函数:
DO language plpgsql $$
DECLARE
filename text := 'xxxx/2013-02/csv/Sales_1302040000-1302050000.zip';
matches text[];
result date;
BEGIN
matches := regexp_matches(filename, E'Sales_(\\d{2})(\\d{2})(\\d{2})');
IF matches IS NOT NULL THEN
result := format('%s-%s-%s', 2000 + matches[1]::int, matches[2], matches[3])::DATE;
raise notice '%', result;
END IF;
END;
$$;
并且regexp_matches似乎在此查询中正常工作,但同样,函数失败并返回null
SELECT
regexp_matches('xxxx/2013-02/csv/Sales_1302040000-1302050000.zip', E'Sales_(\\d{2})(\\d{2})(\\d{2})'),
get_import_batch_date('xxxx/2013-02/csv/Sales_1302040000-1302050000.zip');
我的代码中是否有一个我没有看到的错误(非常可能且最常见的答案)或者我有什么不能在这里做的事情?
我正在使用PostgreSQL 9.1.6
最后一点:给定此文件名,我希望函数返回日期值2013-02-04
答案 0 :(得分:2)
问题结果是对pgAdmin中pgScript的混淆。 @David在pgAdmin的查询工具中按F6运行pgScript而不是 F5 来运行SQL脚本。请参阅comments below 功能本身很好。
我无法重现您的错误(在Postgres 9.1.6上测试过,没有返回NULL
),但我可以为您提供更简单的函数版本不会失败:
CREATE OR REPLACE FUNCTION get_import_batch_date(filename text, OUT result date)
AS
$func$
BEGIN
result := ('20' || substring(filename, E'Sales_(\\d{6})'))::date;
IF result IS NULL THEN
RAISE WARNING 'Unable to determine batch date from %', filename;
END IF;
END
$func$ LANGUAGE plpgsql IMMUTABLE;
OUT
参数来简化操作。不需要相当复杂的regexp_matches()
表达式及其所需的数组转换。
一个简单的substring()
调用完成了这项工作。前置20
并转换为date
。格式符合ISO 8601日期格式,该格式在任何区域设置中有效。您的原始版本也依赖于此,只需添加连字符(-
),这是可选的。
`'20130204'::date` works just as well as `'2013-02-04'::date`
RETURN
,OUT
参数result
的值会自动返回。答案 1 :(得分:1)
也适用于此:http://sqlfiddle.com/#!1/d084b/1
你确定这是传递给get_import_batch_date的文件名吗?
答案 2 :(得分:0)
确定!我终于弄明白了。我不确定为什么会发生这种情况,或者发生了什么,但我至少可以解决它。我在这里发布的答案实际上是基于Erwin的答案。他的代码(像往常一样)比我的更好,但是如果其他人在将来遇到这个非常令人沮丧的问题,那么这种方法很有用。
基本上,今晚我再次玩弄它,终于引起了我的注意。如果我拿这个代码:
CREATE OR REPLACE FUNCTION get_import_batch_date(in filename text, out result date) AS
$BODY$
DECLARE
BEGIN
result := substring(filename, E'Sales_(\\d{6})')::date;
IF result IS NULL THEN
RAISE WARNING 'Unable to determine batch date from %', filename;
END IF;
END
$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100;
...并点击F6到“运行脚本”,您会收到以下消息:
[QUERY ] CREATE OR REPLACE FUNCTION get_import_batch_date(in filename text, out result date) AS
$BODY$
DECLARE
BEGIN
result := substring(filename, E'Sales_(\d{6})')::date;
IF result IS NULL THEN
RAISE WARNING 'Unable to determine batch date from %', filename;
END IF;
END
$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100
你能发现关键问题吗?我不能昨晚,但今晚做了。它正在剥离子字符串函数中的一个“\”。
这将导致匹配失败并返回NULL。
如果你点击F5或单击“运行”按钮该功能,那么它工作正常。 (这可能是人们正在做的事情,也可能是SQLFiddle正在做的事情(这里总猜)。
为了让F6适合我,我不得不将线路更改为:
result := substring(filename, E'Sales_(\\\d{6})')::date;
那么,这对我有用。这感觉就像某个地方的错误。但是,我不知道在哪里。也许@Erwin可以对此有所了解。