Процедура преобразования из Oracle в DB2, ошибка при попытке обновить таблицу во время выполнения - PullRequest
0 голосов
/ 16 октября 2019

Здравствуйте, эксперты DB2! Мне нужна ваша помощь в преобразовании приведенной ниже процедуры в нечто более динамичное. Мы должны обновить несколько последовательностей с максимумом столбца id для каждой таблицы.

CREATE PROCEDURE mySchema.UPDATE_SEQUENCE ( )
 DYNAMIC RESULT SETS 1
 MODIFIES SQL DATA
----------------------------------------------------------------------
-- SQL Stored Procedure
----------------------------------------------------------------------
P1: BEGIN
 DECLARE counter BIGINT;
 DECLARE q VARCHAR(500);
set (counter) = (select max(N_PRI_KEY) from mySchema.myTable);
set q = 'alter sequence mySchema.mySequence RESTART WITH ' || counter;
 EXECUTE IMMEDIATE q;

END P1
@

Это то, что я написал из приведенного выше кода: Здесь я хочу, чтобы N_PRI_KEY был динамическим, а mySchema.myTable обновлялся во время выполнения значениями из таблицы.

CREATE OR REPLACE PROCEDURE getText ()
LANGUAGE SQL
DYNAMIC RESULT SETS 1
  BEGIN
  DECLARE maxval  INTEGER DEFAULT 0;

  CALL DBMS_OUTPUT.PUT( 'a' );

  FOR vrows AS 
      SELECT NAME, SEQUENCENAME, TBNAME FROM MAXSEQUENCE WHERE SEQUENCENAME='ASSETSEQ'
    DO 

      SELECT MAX(vrows.NAME) INTO maxval FROM vrow.TBNAME; -- This is where I am getting error.

    EXECUTE IMMEDIATE 'ALTER SEQUENCE '||vrows.SEQUENCENAME||' RESTART WITH '|| maxval;

  END FOR;      
END@

Это ошибка, которую я получаю при попытке создать процедуру.

DB21034E  The command was processed as an SQL statement because it was not a
valid Command Line Processor command.  During SQL processing it returned:
SQL0204N  "VROW.TBNAME" is an undefined name.  LINE NUMBER=18.  SQLSTATE=42704

Когда я запускаю эту строку, она работает и вставляет максимальное значение в таблицу TEMPOUTPUT. .

execute immediate  'INSERT INTO TEMPOUTPUT VALUES (select max('||vrow.NAME||') from '||vrow.TBNAME||')';

Я пытался сделать это, но это не сработало.

execute immediate  'ALTER SEQUENCE '||SEQUENCENAME||' RESTART WITH select max('||vrow.NAME||') from '||vrow.TBNAME;

Только для справки - это процедура, написанная на языке Oralce, которая делает нечто подобное.


declare
    maxval int;
    seqval int;
  begin
  for i in ( select ucc.column_name, s.sequence_name, uc.table_name
             from   user_cons_columns ucc,
                    user_constraints uc,
                    user_sequences s
             where  uc.constraint_name = ucc.constraint_name
             and    uc.constraint_type = 'P'
             and    ucc.position = 1
             and    s.sequence_name = 'SEQ_'||uc.table_name
           )
  loop
    execute immediate  'select max('||i.column_name||') from '||i.table_name into maxval;
    execute immediate 'select '||i.sequence_name||'.nextval from dual' into seqval;

    dbms_output.put_line(maxval||','||seqval);

     if maxval > seqval then
        execute immediate  'alter sequence '||i.sequence_name||' increment by '|| ( maxval - seqval );
        execute immediate 'select '||i.sequence_name||'.nextval from dual' into seqval;
        execute immediate  'alter sequence '||i.sequence_name||' increment by 1';
        execute immediate 'select '||i.sequence_name||'.nextval from dual' into seqval;
        dbms_output.put_line(maxval||','||seqval);
     end if;
  end loop;
  end;

1 Ответ

0 голосов
/ 17 октября 2019

Попробуйте выполнить следующее вместо строки с SELECT MAX(...), где вы получите ошибку:

PREPARE S1 FROM 'SET ? = (SELECT MAX(' || vrows.NAME || ') FROM ' || vrows.TBNAME || ')';
EXECUTE S1 INTO maxval;
...