我卷起通过计数一个巨大的表到一个新表,在这里我想改变所有的空字符串NULL
,并强制转换的一些列的为好。 我通过一些岗位的阅读,我无法找到一个查询,这将让我做所有列在一个单一的查询,而无需使用多个语句。
让我知道,如果它可以让我在所有的列进行迭代,并与空空字符串替换电池。
参考: 如何空的空间转换为空值,使用SQL Server?
我卷起通过计数一个巨大的表到一个新表,在这里我想改变所有的空字符串NULL
,并强制转换的一些列的为好。 我通过一些岗位的阅读,我无法找到一个查询,这将让我做所有列在一个单一的查询,而无需使用多个语句。
让我知道,如果它可以让我在所有的列进行迭代,并与空空字符串替换电池。
参考: 如何空的空间转换为空值,使用SQL Server?
据我所知,没有内置函数跨表中的所有列替换空字符串。 你可以写一个PLPGSQL功能采取的照顾。
下面的函数替换与给定表的所有基本特征类型的列空字符串NULL
。 然后,您可以转换为integer
,如果剩下的字符串是有效的数字文字。
CREATE OR REPLACE FUNCTION f_empty2null(_tbl regclass, OUT updated_rows int) AS
$func$
DECLARE
-- basic char types, possibly extend with citext, domains or custom types:
_typ CONSTANT regtype[] := '{text, bpchar, varchar, \"char\"}';
_sql text;
BEGIN
SELECT INTO _sql -- build command
format('UPDATE %s SET %s WHERE %s'
, _tbl
, string_agg(format($$%1$s = NULLIF(%1$s, '')$$, col), ', ')
, string_agg(col || $$ = ''$$, ' OR '))
FROM (
SELECT quote_ident(attname) AS col
FROM pg_attribute
WHERE attrelid = _tbl -- valid, visible, legal table name
AND attnum >= 1 -- exclude tableoid & friends
AND NOT attisdropped -- exclude dropped columns
AND NOT attnotnull -- exclude columns defined NOT NULL!
AND atttypid = ANY(_typ) -- only character types
ORDER BY attnum
) sub;
-- Test
-- RAISE NOTICE '%', _sql;
-- Execute
IF _sql IS NULL THEN
updated_rows := 0; -- nothing to update
ELSE
EXECUTE _sql;
GET DIAGNOSTICS updated_rows = ROW_COUNT; -- Report number of affected rows
END IF;
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT f_empty2null('mytable');
SELECT f_empty2null('myschema.mytable');
也得到了列名updated_rows
:
SELECT * FROM f_empty2null('mytable');
SQL小提琴。
表名称必须是有效的,并可见,主叫用户必须拥有所有必需的权限。 如果其中任何一个条件不满足,则函数不会做任何事情 - 即没有任何东西可以被摧毁,无论是。 我投的对象标识符类型regclass
,以确保这一点。
表名可以被提供为是( 'mytable'
),则search_path
决定。 或模式限定的挑选一定的模式( 'myschema.mytable'
)。
查询系统目录来获取所有( 字符类型 )的表列。 所提供的功能,使用这些基本字符类型 : text
, bpchar
, varchar
, "char"
。 只有相关列进行处理。
使用quote_ident()
或format()
消毒列名和防范SQLI 。
更新后的版本使用基本的SQL聚合函数string_agg()
来构建的命令字符串不循环,这是更简单,更快。 ,更优雅。 :)
必须使用动态SQL EXECUTE
。
更新后的版本不包括列定义NOT NULL
,且只能在一个声明 ,这是与多个字符类型列的表要快得多,一旦更新每一行。
如果有任何现代版本的PostgreSQL工作。 经测试在Postgres 9.1,9.3和9.5。