使用类型(&Quot;Text&Quot;)的字符串表示将值转换为类型(Text) [英] Cast value to type (TEXT) using string representation of type ("TEXT")

查看:19
本文介绍了使用类型(&Quot;Text&Quot;)的字符串表示将值转换为类型(Text)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个函数,它试图将一组值转换为用户指定的类型(默认为文本)。一个非常简单的函数将如下所示:

CREATE OR REPLACE FUNCTION cast_to(variable jsonb, key text, target_type anyelement DEFAULT 'TEXT'::regtype) RETURNS anyelement as $$
begin
    RETURN CAST(variable->>key AS target_type);
end
$$
language plpgsql;

我尝试了以下方法:

  1. SELECT CAST('foo' AS 'text');:给出语法错误
  2. SELECT CAST('foo' AS 'text'::regtype);:与%1错误相同
  3. SELECT CAST('foo' AS pg_typeof(null::text));表示type pg_typeof does not exist

最后一次尝试的想法是,我可以用目标类型传递一个变量,而不是文本表示形式。然后,使用该函数将看起来像SELECT cast_to('text', NULL::text);

如何实现此功能或类似功能?

编辑:正如评论中所建议的,我尝试使用动态SQL。我运气不太好。我创建了一个非常基本的案例,它不使用任何变量:

CREATE OR REPLACE FUNCTION audit.cast_to() RETURNS text as $$
DECLARE 
_sql TEXT := 'SELECT CAST($1 AS $2)';
out TEXT;
begin
    EXECUTE _sql
    USING 'foo', 'TEXT'
    INTO out;
    return out;
end
$$
language plpgsql;

但引发错误:

syntax error at or near "$2"

推荐答案

实际上,这是可以做到的。即使没有动态SQL。表面上也很简单。

CREATE FUNCTION cast_to(_js jsonb, INOUT _target_type anyelement = NULL::text) AS
$func$
BEGIN
   SELECT _js ->> pg_typeof(_target_type)::text
   INTO   _target_type;
END
$func$  LANGUAGE plpgsql;

数据库;>小提琴here

但这个极简主义函数包含了几个高级/棘手的细节:请参阅此处的最后一章了解基本信息:

难题的最后一块是将text运算符返回的text值转换为返回类型。一个简单的SQL函数对此要求很严格,不接受text,比如说,一个integer。(也不适用于由多态输入参数的实际输入定义的integer。对于试图简单地RETURN的PL/pgSQL函数也是如此。需要显式强制转换。

CAST (expression AS type) is not a normal function。短句法expression::type也不是。这些是构造语法元素。您可能已经注意到类型名称不带单引号,即:asIDENTIFIER。(您遗漏了该详细信息,这是您报告的前3个语法错误的原因。)并且不能在SQL中对标识符进行参数化。这将需要动态SQL。

但是,我们可以将表达式的text结果赋给(必须键入的)变量或参数,以轻松实现相同的结果。INTO子句将实现这一点。为方便起见,我直接给INOUT参数_target_type赋值。因此_target_type有几个用途:

  1. 定义多态返回类型。

  2. 定义与JSON->>运算符一起使用的键名。该名称由_target_type类型携带,我使用pg_typeof()提取它-它实际上返回regtype,因此我们需要将显式转换为文本。
    注意:这始终会导致Postgres标准类型名称,例如:‘INTEGER’,而不是‘int’或‘int4’。如果您的密钥名称与默认的postgres类型名称不同,则必须像在原始设计中一样传递一个额外的参数!

  3. 用作OUT参数(因此我们不需要DECLARE变量),可以将其赋值给。

  4. 有一个DEFAULT值:= NULL::text,因此可以省略第二个参数,只返回text
    您在原始版本中尝试了该功能,但DEFAULT 'TEXT'::regtype偏离了目标。

您可能希望将其中一些用途拆分为多个参数/变量。

这样就可以做到了。
问题是:您为什么要这样做?通常,有一个更快、更简单的解决方案--即使更冗长。

这篇关于使用类型(&Quot;Text&Quot;)的字符串表示将值转换为类型(Text)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆