2015-04-16 1 views
0

Я две таблицы, тета и convergence_table, каждый из которых имеет одинаковое число столбцов (7 столбцов здесь) (w0, w1, ... W6 ; j0, j1, ... j6). Мне нужно обновить значения «w» как wn = wn-jn. Здесь я обновляю значения таблицы theta с помощью пользовательских типов данных wt & jt (% rowtype).значения Обновление «п» столбцов таблицы с помощью динамического запроса

select * into jt from convergence_table;     
select * into wt from theta 

update theta        
    set w0 = wt.w0-jt.j0, w1 = wt.w1-jt.j1, w2 = wt.w2-jt.j2,  
     w3 = wt.w3-jt.j3, w4 = wt.w4-jt.j4, w5 = wt.w5-jt.j5, 
     w6 = wt.w6-jt.j6; 

Но теперь я «п + 1» число столбцов для обоих тета & convergence_table, поэтому вместо того, чтобы писать заявление обновления и установить все значения из w0, w1, w2 .... wn. Есть ли способ написать динамический запрос для выполнения обновления для всех значений столбца от w0 до wn.

Я пытаюсь следующий код, но он не работает ..

Это дает мне ошибку ...

ERROR: missing FROM-clause entry for table "wt" 
LINE 1: update theta set w0 = wt.w0 - jt.j0,w1 = wt.w1 - jt.j1,w2 = ... 
          ^
QUERY: update theta set w0 = wt.w0 - jt.j0,w1 = wt.w1 - jt.j1,w2 = wt.w2 - jt.j2,w3 = wt.w3 - jt.j3,w4 = wt.w4 - jt.j4,w5 = wt.w5 - jt.j5,w6 = wt.w6 - jt.j6; 
CONTEXT: PL/pgSQL function sample(integer) line 20 at EXECUTE statement 

********** Error ********** 

ERROR: missing FROM-clause entry for table "wt" 
SQL state: 42P01 
Context: PL/pgSQL function sample(integer) line 20 at EXECUTE statement 

Может кто-нибудь помочь с этим?

+0

В принципе, это можно легко сделать в plpgsql. Однако сначала проясните задачу. Вы хотите * 'UPDATE' *, но нет определения того, как сопоставлять строки. Вы думаете, что в каждой таблице есть только одна строка? В 'UPDATE' обычно есть хотя бы один столбец, который не изменяется. Если вы измените все столбцы, вы можете также «УДАЛИТЬ» И «ВСТАВИТЬ», но вам все равно нужно определить * what * для удаления ... –

+0

Да, таблица theta & covergence имеет только одну строку с столбцами «n».В таблице «Покрытие» устанавливается набор случайных значений на каждой итерации, поэтому я должен обновить тета соответственно (Wn = W (n-1) -Jn). Это сценарий. i.e Convergence (J), theta (W) Первоначально (null), (5,4,4,3,3,4,4) После 1-го итера. (1,2,3,2,1,4,3) -> (4,2,1,1,2,0,1) 2-я итерация (2,0,1,2,1,3,2) -> (2,2,0, -1,1, -3, -1) My theta table на конце (2,2,0, -1,1, -3, -1). Обычно у меня будет 1000 итераций. –

+0

Извините, я не могу прикрепить изображение, так как я всего лишь новичок. @ErwinBrandstetter –

ответ

0

Вы можете использовать команду PL/pgsql EXECUTE, построив строку запроса с information_schema.columns.

+0

Извините, я новичок в PostgreSQL и не знаком с этим. Есть ли способ изменить мой код выше и получить ответ? @ Politank-Z –

+0

http://stackoverflow.com/questions/9643859/postgres-missing-from-clause-entry-error-on-query-with-with-clause –

+0

Если я не ошибаюсь, предложение здесь не поможет, wt & jt являются определяемыми пользователем типами (rowtype). и это действительно дало бы мне еще одну ошибку, говорящую, что jt & wt не существует. @ Politank-Z –

1
CREATE OR REPLACE FUNCTION f_upd_dyn(_source regclass, _target regclass) 
    RETURNS void AS 
$func$ 
DECLARE 
    source_cols text; 
    target_cols text; 
BEGIN 
    SELECT INTO source_cols 
      string_agg(quote_ident(attname), ', s.' ORDER BY attname) 
    FROM pg_attribute 
    WHERE attrelid = _source 
    AND NOT attisdropped    -- no dropped (dead) columns 
    AND attnum > 0;     -- no system columns 

    SELECT INTO target_cols 
      string_agg(quote_ident(attname), ', ' ORDER BY attname) 
    FROM pg_attribute 
    WHERE attrelid = _target 
    AND NOT attisdropped    -- no dropped (dead) columns 
    AND attnum > 0;     -- no system columns 

    EXECUTE format('UPDATE %s t 
        SET (%s) = (s.%s) -- prepend 1st table qual s. 
        FROM %s s' 
        -- WHERE t.? = s.? -- how to join source and target? 
       , _target::text, target_cols 
       , source_cols, _source::text 
       ); 
END 
$func$ LANGUAGE plpgsql; 

Вызов:

SELECT f_upd_dyn('convergence_table', 'theta'); 

Формирует и выполняет код, как:

UPDATE theta t SET (w1, w2, w3) = (s.j1, s.j2, s.j3) 
FROM convergence_table s 
-- note the missing WHERE condition! 

SQL Fiddle.

Вы спрашивали подобный вопрос в последнее время:

Есть ссылки на более подробное объяснение. Как это: