我正在尝试编写一个查询,告诉表s
中名为a.t
的列是否具有其默认值(这是一个非常大的base64字符串)。所以我试过了:
SELECT 1 FROM a.t WHERE s = (
SELECT column_default FROM information_schema.columns
WHERE (table_schema, table_name, column_name) = ('a', 't', 's'))
AND uname = 'joe';
哪个没有用,所以我注意到information_schema.columns
的结果有一些东西,常规查询没有:
SELECT column_default FROM information_schema.columns
WHERE (table_schema, table_name, column_name) = ('a', 't', 's');
column_default | 'data:image/png;base64,iVBO...QmCC'::text
Vs以上。
SELECT s FROM a.t WHERE uname = 'joe';
s | data:image/png;base64,iVBO...QmCC
请注意缺少引号和显式演员
这是为什么它不匹配?列s
定义为类型text
如何更改查询以便我可以测试列值与其默认值之间的相等性?
答案 0 :(得分:2)
从信息模式(或我的解决方案中的系统目录)中检索的内容只是表示表达式的字符串文字。您需要实际执行来获取 值 。它可以是一个简单的演员,就像你的情况或任何其他表达式。这就是您需要动态SQL 的地方。 (或者从第一个查询的结果中连接客户端中的第二个查询。)
本相关答案的详细解释:
Generate DEFAULT values in a CTE UPSERT using PostgreSQL 9.3
(您还可以在那里找到替代路线 没有 动态SQL的说明。)
这个DO
statement可以解决问题。
DO
$do$
DECLARE
_data text := 'data:image/png;base64,iVBO...QmCC';
_answer bool;
BEGIN
EXECUTE (
SELECT format('SELECT %s = $1', d.adsrc)
FROM pg_attribute a
JOIN pg_attrdef d ON (d.adrelid, d.adnum) = (a.attrelid, a.attnum)
WHERE a.attrelid = 'a.t'::regclass -- schema.table
AND a.attname = 's'
)
USING _data
INTO _answer;
RAISE NOTICE '%', answer;
END
$do$;
对于重复使用,我会将其包装到plpgsql函数中。有很多相关的答案。
另请注意,列默认值可能会产生副作用,例如增加序列。不是在这种特殊情况下,但通常我建议在执行之前检查默认的。