Иногда на жизненном пути попадаются задачи, в которых нужно обойти столбцы в таблице с неизвестной структурой. Допустим, есть таблица, в которой заказчики обожают добавлять, удалять и изменять столбцы, а вам нужно завязать какую-то логику на все столбцы, столбцы определенного типа, и так далее.
В этом случае, если вы испытываете вполне понятное отвращение, к тому, чтобы каждый раз менять код приложения, вам придется воспользоваться dynamic SQL. (Если вы испытываете отвращение и к dynamic SQL тоже, у меня для вас плохие новости...)
Рассмотрим пример кода, как это может работать
На что надо обратить внимание:
В этом случае, если вы испытываете вполне понятное отвращение, к тому, чтобы каждый раз менять код приложения, вам придется воспользоваться dynamic SQL. (Если вы испытываете отвращение и к dynamic SQL тоже, у меня для вас плохие новости...)
Рассмотрим пример кода, как это может работать
create or replace package Test_Dynamic_Col is /* важная переменная, с помощь которой мы будем обходить поля в таблице */ some_rec sometable%rowtype; end; / create or replace procedure test_proc( p_some_rec sometable%rowtype ) is v_attr_value varchar2(30); begin /* Скидываем значение в глобальную переменную */ Test_Dynamic_Col.some_rec := p_some_rec; /* Выбираем нужные поля */ for attr in (select column_name, data_type from user_tab_columns where table_name = 'SOMETABLE') loop execute immediate 'begin :1 := Test_Dynamic_Col.some_rec.' || attr.column_name || '; end;' using out v_attr_value; /* Здесь логика, по вашему усмотрению */ dbms_output.put_line(attr.column_name || ' is ' || v_attr_value); end loop; end;
На что надо обратить внимание:
- Глобальная переменная может быть объявлена либо в спецификации этого пакета, либо в спецификации другого пакета, но не в теле самого пакета, иначе dynamic SQL не заметит её при выполнении.
- Параметры в Dynamic SQL должны быть SQL типов.
- Запись в PL/SQL не должна быть SQL типа.
Комментариев нет:
Отправить комментарий