Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Oracle > Select - Динамичное переоброзование даты


Автор: flashmaster2008 20.3.2008, 12:18
У нас существует клиентское приложение написанное на Oracle Forms.
В 50 местах применяется запрос вида select * from calls_00_032008;
При переходе на новый месяц мы изменяем руками приложение в 50 местах.
Как нам Автоматизировать процесс подстановки имени таблицы с текущим номером месяца в запрос в качестве источника данных??

Автор: Sqlninja 20.3.2008, 12:23
Если есть возможность сформировать SQL руками, то

Код

sql:= 'select * from calls_00_'||to_char(sysdate,'MMYYYY');

Автор: flashmaster2008 20.3.2008, 12:54
Цитата(Sqlninja @  20.3.2008,  12:23 Найти цитируемый пост)
sql:= 'select * from calls_00_'||to_char(sysdate,'MMYYYY');


Цитата(Sqlninja @  20.3.2008,  12:23 Найти цитируемый пост)
sql:= 'select * from calls_00_'||to_char(sysdate,'MMYYYY');


 Я понял я хочу чтобы это все автоматизировать, как при открытие запроса, оно сама менялось, строку имею виду select * from calls_00_032008 на текущий месяц

Ребята примеры дали но оно неработает, Помогите решит мою проблему, Пожалуйста, Заранее благодарью  

1. select to_char(sysdate,'MMYYYY') from dual


select * from (select 'calls_00_'||to_char(sysdate,'MMYYYY') as calls from dual)


select * from calls_00_032008


2.select * from table(fn('calls_00_'||to_char(sysdate,'MMYYYY')));
где fn-табличная функция, в которой есть d-sql

3. ефкурсор для работы, селект формировать динамически,
типа 
str:='select * from calls_00_'||to_char(sysdate,'MMYYYY');
Насколько я помню, там засада будет только с разбором строки по столбцам, надо чтобы структура таблички была фиксирована по типам

4.Маленький примерчик динамического sql.
Вот так можно сделать для получения одного значения:
Код

declare
  v_date date;
  v_table_name varchar(100);
  v_query varchar(100);
begin
  select 'calls_00_'||to_char(sysdate,'MMYYYY') into v_table_name from dual;
  --dbms_output.PUT_LINE(v_table_name);
  v_query := 'begin select sysdate into :variable from ' || v_table_name || 'where rownum = 1; end;';
  execute immediate v_query using out v_date;
  dbms_output.PUT_LINE(v_date);
end;

для получения всех данных, как говорил Наивый людь, нужно использовать курсор.

5.
Код

CREATE OR REPLACE PROCEDURE copy ( 

     source      IN VARCHAR2, 

     destination IN VARCHAR2) IS 

     id_var             NUMBER; 

     name_var           VARCHAR2(30); 

     birthdate_var      DATE; 

     source_cursor      INTEGER; 

     destination_cursor INTEGER; 

     ignore             INTEGER; 

  BEGIN 



  -- Prepare a cursor to select from the source table: 

     source_cursor := dbms_sql.open_cursor; 

     DBMS_SQL.PARSE(source_cursor, 

         'SELECT id, name, birthdate FROM ' || source, 

          DBMS_SQL.NATIVE); 

     DBMS_SQL.DEFINE_COLUMN(source_cursor, 1, id_var); 

     DBMS_SQL.DEFINE_COLUMN(source_cursor, 2, name_var, 30); 

     DBMS_SQL.DEFINE_COLUMN(source_cursor, 3, birthdate_var); 

     ignore := DBMS_SQL.EXECUTE(source_cursor); 



  -- Prepare a cursor to insert into the destination table: 

     destination_cursor := DBMS_SQL.OPEN_CURSOR; 

     DBMS_SQL.PARSE(destination_cursor, 

                  'INSERT INTO ' || destination || 

                  ' VALUES (:id_bind, :name_bind, :birthdate_bind)', 

                   DBMS_SQL.NATIVE); 



  -- Fetch a row from the source table and insert it into the destination table: 

     LOOP 

       IF DBMS_SQL.FETCH_ROWS(source_cursor)>0 THEN 

         -- get column values of the row 

         DBMS_SQL.COLUMN_VALUE(source_cursor, 1, id_var); 

         DBMS_SQL.COLUMN_VALUE(source_cursor, 2, name_var); 

         DBMS_SQL.COLUMN_VALUE(source_cursor, 3, birthdate_var); 



  -- Bind the row into the cursor that inserts into the destination table. You 

  -- could alter this example to require the use of dynamic SQL by inserting an 

  -- if condition before the bind. 

        DBMS_SQL.BIND_VARIABLE(destination_cursor, ':id_bind', id_var); 

        DBMS_SQL.BIND_VARIABLE(destination_cursor, ':name_bind', name_var); 

        DBMS_SQL.BIND_VARIABLE(destination_cursor, ':birthdate_bind', birthdate_var); 

        ignore := DBMS_SQL.EXECUTE(destination_cursor); 

      ELSE 



  -- No more rows to copy: 

        EXIT; 

      END IF; 

    END LOOP; 



  -- Commit and close all cursors: 

     COMMIT; 

     DBMS_SQL.CLOSE_CURSOR(source_cursor); 

     DBMS_SQL.CLOSE_CURSOR(destination_cursor); 

   EXCEPTION 

     WHEN OTHERS THEN 

       IF DBMS_SQL.IS_OPEN(source_cursor) THEN 

         DBMS_SQL.CLOSE_CURSOR(source_cursor); 

       END IF; 

       IF DBMS_SQL.IS_OPEN(destination_cursor) THEN 

         DBMS_SQL.CLOSE_CURSOR(destination_cursor); 

       END IF; 

       RAISE; 

  END;

6.create synonym calls_syn for calls_00_032008;

Автор: Sqlninja 20.3.2008, 13:21
Ну правильно , для того SYSDATE и указан чтобы подтягивать автоматом дату и из нее получать имя таблицы. Где ты текст SQL пишешь? Тебе строку надо изменить или чего то другое?

Автор: flashmaster2008 20.3.2008, 13:33
Мне менять надо строку, calls_00_032008.  Я пишу на PL/SQL Help me Please !

Для примера calls_00_032008 на calls_00_042008 - строка должна реагировать на текущий месяц.

У нас каждый месяц создается таблица ! calls. Пробле в то что у нас много запросов, которые имеют строку calls_00_-текущий месяц

Автор: Sqlninja 20.3.2008, 15:09
Код

declare 
  l_old_string   varchar2(100) := 'calls_00_022008';
  l_new_string varchar2(100);
  l_date_piece varchar2(20);
  l_sql              varchar2(100) := 'select * from ';
begin
  select to_char(sysdate,'mmyyyy') into l_date_piece from dual;
  l_new_string := 'calls_00_'||l_date_piece; 
  l_sql:= l_sql || l_new_string;
  dbms_output.put_line(l_sql);
end;


Получаем:

select * from calls_00_032008

Автор: DimW 21.3.2008, 09:41
Цитата(flashmaster2008 @  20.3.2008,  12:18 Найти цитируемый пост)
Как нам Автоматизировать процесс подстановки имени таблицы с текущим номером месяца в запрос в качестве источника данных?? 

1) используя пример Sqlninja, можешь написать функцию которая с учетом текущей даты возвратит данные.
2) на основе этой функции делаешь вьюху
3) подставляешь во все 50 мест селект из вьюхи

Автор: puncher 21.3.2008, 15:39
обычно делают таблицу, где ведут расчетный месяц, дату начала и дату конца.
и все отчеты ссылаются на расчетный месяц.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)