选择查询中的动态类型转换

时间:2015-12-14 12:57:05

标签: sql arrays json postgresql casting

由于对问题的描述不准确,我完全重写了我的问题!

我们必须存储关于特定区域的许多不同信息。为此,我们需要一个灵活的数据结构,这不会限制用户的可能性。

因此,我们为此附加数据创建了键值表,这是通过元表描述的,其中包含值的数据类型。

我们已经将此信息用于我们的其他API的查询。然后,我们将请求的字段自动换行到cast

enter image description here SQL Fiddle

我们将这些数据与其他表格中的信息一起作为JSON对象返回。我们将数据表中的相应行与array_aggjson_object转换为JSON对象:

...
CASE
    WHEN count(prop.name) = 0 THEN '{}'::json
    ELSE json_object(array_agg(prop.name), array_agg(prop.value))
END AS data
...

这非常有效。现在我们遇到的问题是,如果我们将数据(如浮点数)存储到此字段中,我们将返回此数字的字符串表示形式:

e.g. 5.231 returns as "5.231"

现在我们希望在select语句中将此数字 CAST 转换为正确的数据格式,以便正确格式化JSON结果。我们拥有所需的所有信息,因此我们尝试了以下内容:

SELECT 
json_object(array_agg(data.name),
            -- here I cast the value into the right datatype! 
            -- results in an error
            array_agg(CAST(value AS datatype))) AS data
FROM data
JOIN (
    SELECT name, datatype
    FROM meta)
AS info
ON info.name = data.name

错误消息如下:

ERROR:  type "datatype" does not exist
LINE 3:    array_agg(CAST(value AS datatype))) AS data
                                   ^
Query failed
PostgreSQL said: type "datatype" does not exist

那么可以动态地将data_type列的文本转换为 postgresql类型以返回格式正确的JSON对象吗?

2 个答案:

答案 0 :(得分:4)

首先,这是一种可怕的SQL滥用,几乎在所有情况下都应该避免使用。如果你有一个合法的场景,你可能已经非常了解你的RDBMS,你正在编写自定义索引插件,甚至不会想到问这个问题...

如果你告诉我们你真正要做的事情,我们可以告诉你一个更好的方法,有99.9%的可能性。

现在放弃这个免责声明:

如果不使用动态SQL,这是不可能的。使用最新版本的PostgreSQL,您可以使用' EXECUTE IMMEDIATE'来完成此操作,您可以阅读in the manual。它基本上归结为使用EXEC

但请注意,即使使用此方法,在同一查询中提取的每一行的结果也必须具有相同的数据类型。换句话说,您不能指望第1行的数据类型为VARCHAR,第2行的数据类型为INT。这完全不可能。

答案 1 :(得分:2)

您遇到的问题是,json_object确实为创建了一个string array对象,为值创建了另一个string array。因此,如果您将 JSON 对象提供给此方法,它将始终返回错误。

所以第一个问题是,您必须为值使用 JSON JSONB 列。或者,您可以使用to_json()将值从字符串转换为json。

现在第二个问题是你需要使用另一种方法来创建你的json对象,因为你想用密钥string array和值json-object array来提供它。为此,有一种名为json_object_agg的方法。

然后你的输出应该像你期望的那样!这里是完整的查询:

SELECT 
json_object_agg(data.name, to_json(data.value)) AS data
FROM data