由于对问题的描述不准确,我完全重写了我的问题!
我们必须存储关于特定区域的许多不同信息。为此,我们需要一个灵活的数据结构,这不会限制用户的可能性。
因此,我们为此附加数据创建了键值表,这是通过元表描述的,其中包含值的数据类型。
我们已经将此信息用于我们的其他API的查询。然后,我们将请求的字段自动换行到cast
。
我们将这些数据与其他表格中的信息一起作为JSON
对象返回。我们将数据表中的相应行与array_agg
和json_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对象吗?
答案 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