我有一个应用程序(作为其逻辑的一部分)在插入数据库之前修剪字符串并用 NULL 替换空字符串。我想确保执行此操作的一种方法是在每个具有VARCHAR
, TEXT
(或类似)列的表上编写一个 CHECK 。
假设一个人不能或不想这样做,有一种方法可以编写一个简单的通用 SQL 查询(从数据库的元数据中获取表和列名),以检查数据库中的任何文本列是否包含空字符串?
我有一个应用程序(作为其逻辑的一部分)在插入数据库之前修剪字符串并用 NULL 替换空字符串。我想确保执行此操作的一种方法是在每个具有VARCHAR
, TEXT
(或类似)列的表上编写一个 CHECK 。
假设一个人不能或不想这样做,有一种方法可以编写一个简单的通用 SQL 查询(从数据库的元数据中获取表和列名),以检查数据库中的任何文本列是否包含空字符串?
正如您所指出的,最好的方法是使用
CHECK
约束,可能通过 aDOMAIN
,例如然后
ALTER
现有列使用域。如果这不可能,您将需要查询
INFORMATION_SCHEMA
以在所有表中查找目标类型的所有列,然后为每一列动态生成一个查询以进行检查。您可以为此使用 PL/PgSQL 和EXECUTE
语句;在 Stack Overflow 的其他地方有很多这样使用它的例子。你不能写一个查询来做你想做的事。它只是行不通。您必须使用从
information_schema
.单表功能
返回给定表的所有字符类型列,其中包含空值计数 (
''
) 以及它们是否已定义NOT NULL
。称呼:
回报:
适用于Postgres 9.1或更高版本。
根据当前的
search_path
.如果需要,输出表名和列名会自动转义。
empty_ct
是列的值为空字符串的行数not_null
报告列是否已定义NOT NULL
(因此您不能将可能的空字符串转换为 NULL!)输入表名可以选择是模式限定的,否则默认为当前的
search_path
.您的角色需要权限才能实际从给定表中读取。
该函数经过高度优化,仅对给定表运行一次扫描以检查所有相关列。
应该可以安全地防止 SQL 注入。
使用并行
unnest()
来稍微简化复杂的代码:您将对 SO 上的这个相关答案感兴趣,以实际替换空字符串- 并提供更多解释:
也匹配仅包含空格字符的字符串
正如您评论的
trim(s.col, ' ') = ''
那样,这项工作做得很好。但这里有一个捷径:如何?
char
是 的别名character(1)
,很少使用的空白填充类型。值用空格字符填充到长度说明符的右侧(1
在这种情况下,但不相关)。对于这种类型,尾随空格实际上是微不足道的。所以与or' '
相同。瞧。是的,它也更快,我测试过。''
' '
要查找仅包含空格字符的字符串(而不是其他空格!),请将强制转换添加到上面的这些行中:
用于报告整个模式的包装函数
称呼:
回报:
db<>fiddle here
旧sqlfiddle