2016-09-22 1 views
0

У меня есть таблица XX_LOCATION с 20 столбцами. Из этого я хочу, чтобы данные содержали всего 4 столбца в покое. 16 Я хочу обновить значения столбцов до нуля.Обновление данных столбца до нуля без записи каждого имени столбца в sql

Как можно использовать 1 оператор утверждения для этого, т. Е. Я не хочу писать каждое имя столбца из 16 столбцов в инструкции обновления. Есть ли другой выход?

+3

Здесь нет короткого замыкания. – jarlh

+0

Или вы имеете в виду значения INSERT? Например. 'INSERT INTO tablename (col1, col2, col3, col4) VALUES (val1, val2, val3, val4)'? Будет установлено значение col5 для col20 в NULL (если для столбцов не заданы значения по умолчанию). – jarlh

+0

Грязный способ ... получить имена столбцов и создать динамический sql ... – Prisoner

ответ

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; 
Смежные вопросы