我有一张20列的XX_LOCATION表。除此之外,我希望在其余16个列中只有4列数据,我想将列值更新为null。
如何使用1更新语句,即我不想在update语句中写入16列的每个列名。还有其他出路吗?
答案 0 :(得分:0)
好的,我承认。我对这个有一点乐趣。
BEGIN
FOR eachrec IN (SELECT column_name
FROM user_tab_cols a
WHERE table_name = 'MYTABLE'
AND column_name NOT IN ('COL1', 'COL2', 'COL3'
, 'COL4'))
LOOP
execute immediate 'update XX_LOCATION set ' || eachrec.column_name || ' = null';
END LOOP;
END;
这是另一种可能性,这个只有一个执行立即执行:
DECLARE
l_cmd VARCHAR2 (2000);
l_comma VARCHAR2 (1);
BEGIN
l_cmd := 'update xx_location set ';
FOR eachrec IN (SELECT column_name
FROM user_tab_cols a
WHERE table_name = 'MYTABLE'
AND column_name NOT IN ('COL1', 'COL2', 'COL3'
, 'COL4'))
LOOP
l_cmd := l_cmd || l_comma || eachrec.column_name || ' = null';
l_comma := ',';
END LOOP;
execute immediate l_cmd;
END;
最后,一个完全自动化的解决方案,可以排除N列,而无需键入未指定的列名称:
CREATE TYPE column_tt IS TABLE OF VARCHAR2 (30);
CREATE OR REPLACE PROCEDURE nullify_columns (
p_owner IN all_tab_cols.owner%TYPE
, p_table IN all_tab_cols.table_name%TYPE
, p_exclude_columns IN OUT NOCOPY column_tt
)
AS
l_cmd VARCHAR2 (2000);
l_comma VARCHAR2 (1);
BEGIN
l_cmd := 'update ' || p_owner || '.' || p_table || ' set ';
FOR eachrec IN (SELECT column_name
FROM all_tab_cols a
WHERE owner = p_owner
AND table_name = p_table)
LOOP
IF NOT eachrec.column_name MEMBER OF p_exclude_columns
THEN
l_cmd := l_cmd || l_comma || eachrec.column_name || ' = null';
l_comma := ',';
END IF;
END LOOP;
EXECUTE IMMEDIATE l_cmd;
END;
CREATE TABLE totally_bogus_dude
(
col1 VARCHAR2 (10)
, col2 VARCHAR2 (10)
, col3 VARCHAR2 (10)
, col4 VARCHAR2 (10)
, col5 VARCHAR2 (10)
);
DECLARE
l_exclude column_tt := column_tt ();
BEGIN
l_exclude.EXTEND;
l_exclude (l_exclude.COUNT) := 'COL1';
l_exclude.EXTEND;
l_exclude (l_exclude.COUNT) := 'COL2';
l_exclude.EXTEND;
l_exclude (l_exclude.COUNT) := 'COL3';
l_exclude.EXTEND;
l_exclude (l_exclude.COUNT) := 'COL4';
FOR eachrec IN (SELECT COLUMN_VALUE
FROM TABLE (l_exclude))
LOOP
DBMS_OUTPUT.put_line (eachrec.COLUMN_VALUE);
END LOOP;
nullify_columns (p_owner => USER, p_table => 'TOTALLY_BOGUS_DUDE', p_exclude_columns => l_exclude);
END;