【问题标题】:Check a whole table for a single value检查整个表的单个值
【发布时间】:2012-04-03 13:57:50
【问题描述】:

背景:我正在将数据库表转换为不支持空值的格式。我想用任意数字替换空值,以便我的应用程序可以支持空值。

问题:我想在整个表格中搜索一个值(例如“999999”)以确保它不出现在表格中。我可以编写一个脚本来单独测试每一列,但我想知道是否有一种方法可以在纯 sql 中执行此操作而无需枚举每个字段。这可能吗?

【问题讨论】:

  • 不要在标题中加上“sql”,这就是标签的作用。

标签: sql postgresql types null pattern-matching


【解决方案1】:

您可以使用 PostgreSQL 类型系统的一个特殊功能:

SELECT *
FROM   tbl t
WHERE  t::text LIKE '%999999%';

对于您在 PostgreSQL 中创建的每个表,都有一个同名的 composite type。 PostgreSQL 中的每种类型都有一个text 表示(用于输入/输出值)。

因此,您可以将整行转换为text,并且如果字符串“999999”包含在任何列中(准确地说是text 表示),则可以保证在上面的查询中显示。

您不能完全排除误报,但是,如果 Postgres 用于行表示的分隔符和/或装饰器可以是搜索词的一部分。这只是非常不太可能。您的搜索词“999999”肯定不是这种情况。

最近在 codereview.SE 上有一个非常相似的问题。我加了some more explanation in my answer there

【讨论】:

  • 您使用~~而不是标准的LIKE运算符有什么特别的原因吗?
  • @a_horse_with_no_name:没有特别的原因。您可能知道这一点,但对于公众来说这是一个奇怪的事实:~~ 虽然是相同的运营商,但在operator precedence 中的排名高于LIKE。所以表达式'ab' LIKE 'a' || '%'需要用括号加上~~'ab' ~~ ('a' || '%')
  • 谢谢。不,我不知道运算符优先级。我尽可能使用标准 SQL(所以我从不使用~~)。这使得 SQL 方言之间的切换更容易。
  • @a_horse_with_no_name:我认为这是一种很好的做法。我修改了我的示例以支持这一点(尽管无论如何这是 Postgres 特定的)。我发现~~ 更容易阅读,并且更容易在~(正则表达式匹配)和~~ 之间切换,而且我主要使用PostgreSQL,所以我喜欢较短的运算符。
  • @ErwinBrandstetter 我不太熟悉 SQL,除了上下文,我不知道 ~~ 是什么意思。谢谢你的回答。
【解决方案2】:
create or replace function test_values( real ) returns setof record as
$$
declare
query text;
output record;
begin
for query in select 'select distinct ''' || table_name || '''::text table_name, ''' || column_name || '''::text column_name from '|| quote_ident(table_name)||' where ' || quote_ident(column_name) || ' = ''' || $1::text  ||'''::' || data_type  from information_schema.columns where table_schema='public'   and numeric_precision is not null
loop
    raise notice '%1 qqqq', query;
    execute query::text into output;
    return next output;
end loop;
return;
end;$$ language plpgsql;

select distinct * from test_values( 999999 ) as t(table_name text ,column_name text)

【讨论】:

    猜你喜欢
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多