我的数据库中有三个不同的值表示null:实际的null,空字符串和字符串{x:Null}
。此值显示在多个列中。
{x:Null}
在Web前端进行了规范化,因此所有这些值看起来完全相同,尽管它们最终在排序中的排序方式不同。如何编写一个查询来获取这些值并使它们在每个列和每个表中都成为实际的空值?
如果您可以告诉我如何确保这些其他空值始终作为空值插入,那么可以告诉我。 (免责声明:我无权授予任何实际奖励积分。;)
答案 0 :(得分:1)
使用information_schema.columns表,编写一个过程语言例程,遍历所有适用的表和列,执行update
... set *column* = NULL
... where column in ('','{x:Null}')
。对于每个符合条件的列。
至于将这些值作为NULL
向前插入,您必须在表格上设置触发器以拦截这些值并将其替换为NULL
。
答案 1 :(得分:1)
您可以查询information_schema以获取字符串类型的所有表和列的列表。
SELECT table_name, column_name
FROM information_schema.columns
WHERE data_type IN ('text', 'character', 'character varying')
注意首先仔细检查data_type
的值是什么,我不确定它是character
还是char
还是什么。
然后我会写一个小程序来更新每个表中的每一列。这里是Perl中的概述。
while( my($table, $column) = $sth->fetch ) {
my $q_table = $dbh->quote($table);
my $q_column = $dbh->quote($column);
$dbh->do(q[
UPDATE `$q_table`
SET `$q_column` = NULL
WHERE `$q_column` = '{x:Null}'
OR `$q_column` = ''
]);
}
请务必按照我的示例中的SQL转义$table
和$column
。
展望未来,您必须在每一列上设置CONSTRAINTS。您也可以使用information_schema.columns来执行此操作。像
这样的东西ALTER TABLE `$q_table` ADD CHECK(`$q_column` NOT IN ('{x:Null}', ''))
您可以使用触发器将值更改为NULL,但我不喜欢为应用程序静默更改基本数据的数据存储。
对于新的列和表,您必须记住添加该约束。关于data_type
的相同警告适用。
但是,说没有列可以成为空字符串可能是个坏主意。你可能想要更有选择性。
另外需要注意的是:NULL是一个有趣的东西,它不是真的,它不是假的。您可能最好决定将空字符串设置为空值。
我不认为这种方法是可维护的。它在整个数据层上涂写应用程序规则。如果您有一些不符合该规则的数据怎么办?并且必须持续维护所添加的任何新数据模式。也许你应该把它放在你的ORM layer。或者写一些存储过程来处理这个问题。
答案 2 :(得分:0)
我认为没有任何查询可以为每个表和每一列做这件事。原则上,你想要做的是
UPDATE table SET column=NULL WHERE column='' OR column='{x:Null}';
您可以尝试从pg_attribute
和pg_class
列中选择数据,以获取表的名称和列的名称,然后自动生成查询。请务必仅选择包含文本数据的列。
如果有人输入了真正的字符串“{x:Null}”怎么办?然后,您可以将其更改为NULL
。
然而,你已经犯了一个真正的错误,让情况变得像现在一样糟糕。在将数据放入数据库之前,应始终对数据进行规范化。