Динамически ссылаться на имя таблицы в SQL-запросе DB2 / 400. - PullRequest
0 голосов
/ 07 ноября 2018

Я бы хотел выполнить запрос, который получает комбинацию текущих данных и метаданных для регулярно меняющегося списка имен таблиц. Это для исследований и анализа на большом сервере с более чем 100 схемами и тысячами таблиц / представлений в каждой. Мне нужна помощь в динамическом обращении к именам таблиц, что, как я понимаю, невозможно. Однако ...

Мой поиск в Google указывает, что решением может быть оператор SQL в текстовой переменной, который затем выполняется оператором EXEC. Но это DB2 / 400 v7r3, которая сложна (как и ссылка на SQL на веб-сайте IBM), и мне трудно создать правильный синтаксис.

Вот базовый пример того, что я хочу сделать, но, конечно, это не работает:

SELECT        TABLE_NAME,
              TABLE_TEXT,
              ( SELECT COUNT(*) FROM TABLE_NAME ) AS ROW_COUNT
              -- above line of course does not work
FROM          QSYS2.SYSTABLES
WHERE         TABLE_SCHEMA = 'ABCDEFGH'
AND           TABLE_NAME IN ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'DAILYHT', 'ETC')

Я понимаю, что мне нужно что-то вроде следующего, но я не могу понять правильные утверждения:

DECLARE       @sqltext AS VARCHAR(128)
SELECT        TABLE_NAME,
              TABLE_TEXT,
              ( SET @sqltext = 'SELECT COUNT(*) FROM ABCDEFGH.' || TABLE_NAME
                EXEC sqltest ) AS ROW_COUNT --this is probably wrong
FROM          QSYS2.SYSTABLES
WHERE         TABLE_SCHEMA = 'ABCDEFGH'
AND           TABLE_NAME IN ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'ETC', 'ETC', 'ETC')
ORDER BY      TABLE_NAME

1 Ответ

0 голосов
/ 08 ноября 2018

Динамический SQL не сложно ...

По сути, встроите оператор SQL в строковую переменную. Использование CONCAT для включения значений из других

@sqlStmt = 'Insert into mytable values (''ConstVal'',' concat SomeVar concat ')';

execute immediate @sqlStmt;

Проблема в том, что вам нужно экранировать строки, например 'ConstVal' выше, с двойными одинарными кавычками.

Другой улов в том, что вы не можете использовать SELECT, как пытаетесь. Если бы у вас была только одна строка для возврата, SELECT INTO была бы опцией для статического оператора. Но не поддерживается для динамического. Вместо этого вы должны использовать динамический VALUES INTO.

Однако, похоже, вы хотите вернуть несколько строк. В этом случае вам нужно использовать курсор. К сожалению, динамические курсоры немного сложнее, так как вы должны использовать дескриптор SQL.

declare myCursor cursor for myStatement;

set @sqlStmt = 'select ....';
prepare myStatement into mySqlDescriptor from @SqlStmt;

open myCursor;
// done if you are returning the results
// assuming you want to process in your procedure..
// add a loop that does 
//   fetch next from myCursor into myData;

Сказав все это, вам не нужно ничего, чтобы получить счетчик строк для таблицы ... представление каталога syspartitionstat уже имеет эту информацию.

select table_name, number_rows 
from syspartitionstat
where table_schema = 'ABCDEFGH' 
      and TABLE_NAME in ('ARCMNTST', 'ARIMSGT', 'ARTENT', 'ETC', 'ETC', 'ETC');
...