将列数据更新为null,而不在sql中写入每个列名

时间:2016-09-22 07:19:29

标签: sql oracle

我有一张20列的XX_LOCATION表。除此之外,我希望在其余16个列中只有4列数据,我想将列值更新为null。

如何使用1更新语句,即我不想在update语句中写入16列的每个列名。还有其他出路吗?

1 个答案:

答案 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;