在我的应用程序中,我在 PostGreSql 中有多个数据库,其中可以包含 500 多个表,每个表可以有 5 到 20 个具有不同数据类型的列。 数据库中的数据是使用外部输入导入的,外部输入不会包含架构中的所有列。由于此 PostGreSql 默认情况下会在表中插入空值。
例如:当我将 json 内容导入到 PostGreSql 时,它没有特定的列及其值存在于 json 中。 PostGreSql 默认插入一个空值。
示例 json 内容 [{“ID”:1,“修订版”:7}]
现在,如果我的表中多包含一列“Name”,则当导入上述 json 内容时,“Name”列包含特定行或任意数量的行的空值。
如何识别这些空值并将其替换为默认值,而不是动态地使用函数或任何其他更好的方法?
例如:Name 列中包含 null 的行应替换为空字符串 或者 布尔类型列应该具有 False 值而不是 null。
以下函数检查表中的
information_schema.columns
是否可以为空列 (is_nullable = 'YES'
)。它查找 NULL
值并根据列类型设置默认值。然后,它动态更新表以将 NULLs
替换为这些默认值。
CREATE OR REPLACE FUNCTION replace_nulls_with_defaults(table_name TEXT) RETURNS VOID AS $$
DECLARE
col RECORD; -- To store column metadata
query TEXT; -- To store dynamic SQL queries
default_val TEXT; -- To determine default value based on column types
BEGIN
FOR col IN
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = table_name
AND is_nullable = 'YES' -- Only nullable columns
LOOP
-- Determine the default value
IF col.data_type IN ('character varying', 'text') THEN
default_val := '''''';
ELSIF col.data_type = 'boolean' THEN
default_val := 'FALSE';
ELSIF col.data_type IN ('integer', 'bigint', 'smallint', 'numeric', 'real', 'double precision') THEN
default_val := '0';
ELSIF col.data_type = 'date' THEN
default_val := 'CURRENT_DATE';
ELSIF col.data_type IN ('timestamp without time zone', 'timestamp with time zone') THEN
default_val := 'CURRENT_TIMESTAMP';
ELSE
RAISE NOTICE 'Skipping column %, unsupported type: %', col.column_name, col.data_type;
CONTINUE;
END IF;
-- Build the dynamic SQL query
query := FORMAT(
'UPDATE %I SET %I = %s WHERE %I IS NULL;',
table_name, col.column_name, default_val, col.column_name
);
EXECUTE query;
END LOOP;
END;
如果运行该函数
SELECT replace_nulls_with_defaults('sample_table');
,所有合适的 NULL 值都将替换为默认值。