Модераторы: Akella

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Имя таблицы входящим параметром, Передача в проц имени табл вход парам 
V
    Опции темы
Alkor135
Дата 26.5.2009, 21:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Написал процедуру (FireBierd 2.1 доступ из Delphi 2009 через InterBase).
Мне нужно, чтобы она работала получая имя таблицы как входящий параметр.
Вот код, когда я задаю имя таблицы как входящий параметр, процедура не компилится (пробовал и с двоеточием):
Код

SET TERM ^ ;

CREATE OR ALTER PROCEDURE AUDCAD_PROC_END (
    i_pair char(6),
    p_input_date_min date,
    p_input_time_min time,
    p_input_date_max date,
    p_input_time_max time)
returns (
    p_pair char(6),
    p_da_min date,
    p_ti_min time,
    p_op numeric(6,5),
    p_da_max date,
    p_ti_max time,
    p_cl numeric(6,5),
    p_point integer,
    p_point_mod integer)
as
begin
  p_pair = I_PAIR;

  /* Если даты не существует, то берем следующую дату (в цикле) */
  while (NOT exists (SELECT da FROM I_PAIR WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
  /* Если время нужной даты не существует, то берем следующее время (в цикле) */
  p_ti_min = P_INPUT_TIME_MIN;
  while (NOT exists (SELECT ti FROM I_PAIR WHERE (da = :p_input_date_min) and ti = :p_ti_min))  do
    p_ti_min = p_ti_min + 1;
  /* Если даты не существует, то берем предыдущую дату (в цикле) */
  while (NOT exists (SELECT da FROM I_PAIR WHERE da = :p_input_date_max))  do
    p_input_date_max = p_input_date_max - 1;
  /* Если время нужной даты не существует, то берем предыдущее время (в цикле) */
  p_ti_max = P_INPUT_TIME_MAX;
  while (NOT exists (SELECT ti FROM I_PAIR WHERE (da = :p_input_date_max) and ti = :p_ti_max))  do
    p_ti_max = p_ti_max - 1;

  SELECT da, ti, op
  FROM I_PAIR
  WHERE (da = :p_input_date_min and ti = :p_ti_min)
  INTO p_da_min, p_ti_min, p_op;

  SELECT da, ti, cl
  FROM I_PAIR
  WHERE (da = :p_input_date_max and ti = :p_ti_max)
  INTO p_da_max, p_ti_max, p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end^

SET TERM ; ^

GRANT EXECUTE ON PROCEDURE AUDCAD_PROC_END TO SYSDBA;


А когда задаю имя таблицы явно, все прекрасно компилируется и работает:
Код

SET TERM ^ ;

CREATE OR ALTER PROCEDURE AUDCAD_PROC_END (
    i_pair char(6),
    p_input_date_min date,
    p_input_time_min time,
    p_input_date_max date,
    p_input_time_max time)
returns (
    p_pair char(6),
    p_da_min date,
    p_ti_min time,
    p_op numeric(6,5),
    p_da_max date,
    p_ti_max time,
    p_cl numeric(6,5),
    p_point integer,
    p_point_mod integer)
as
begin
  p_pair = I_PAIR;

  /* Если даты не существует, то берем следующую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
  /* Если время нужной даты не существует, то берем следующее время (в цикле) */
  p_ti_min = P_INPUT_TIME_MIN;
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_min) and ti = :p_ti_min))  do
    p_ti_min = p_ti_min + 1;
  /* Если даты не существует, то берем предыдущую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_max))  do
    p_input_date_max = p_input_date_max - 1;
  /* Если время нужной даты не существует, то берем предыдущее время (в цикле) */
  p_ti_max = P_INPUT_TIME_MAX;
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_max) and ti = :p_ti_max))  do
    p_ti_max = p_ti_max - 1;

  SELECT da, ti, op
  FROM audcad
  WHERE (da = :p_input_date_min and ti = :p_ti_min)
  INTO p_da_min, p_ti_min, p_op;

  SELECT da, ti, cl
  FROM audcad
  WHERE (da = :p_input_date_max and ti = :p_ti_max)
  INTO p_da_max, p_ti_max, p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end^

SET TERM ; ^

GRANT SELECT ON AUDCAD TO PROCEDURE AUDCAD_PROC_END;

GRANT EXECUTE ON PROCEDURE AUDCAD_PROC_END TO SYSDBA;


Подскажите как в процедуру передать имя таблицы как входящий параметр?

Это сообщение отредактировал(а) Alkor135 - 27.5.2009, 00:45
PM MAIL   Вверх
Akella
Дата 26.5.2009, 22:37 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Пока не могу сообразить. Но, наверное, придётся использовать execute statement

Добавлено через 3 минуты и 59 секунд
Примеры>>

Добавлено через 5 минут и 43 секунды
Кстати, источник:
Цитата

Источник

($firebird)/doc/sql.extensions/README.execute_statement.txt

($firebird)/doc/sql.extensions/README.execute_statement2.txt


PM MAIL   Вверх
Alkor135
Дата 27.5.2009, 00:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Akella @ 26.5.2009,  22:37)
Пока не могу сообразить. Но, наверное, придётся использовать execute statement

Добавлено @ 22:41
Примеры>>

Добавлено @ 22:43
Кстати, источник:
Цитата

Источник

($firebird)/doc/sql.extensions/README.execute_statement.txt

($firebird)/doc/sql.extensions/README.execute_statement2.txt


Спасибо, буду разбираться.
PM MAIL   Вверх
Deniz
Дата 27.5.2009, 06:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Alkor135, опиши задачу, может обойдемся без execute statement


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Alkor135
Дата 27.5.2009, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Deniz @ 27.5.2009,  06:39)
Alkor135, опиши задачу, может обойдемся без execute statement

У меня есть 27 таблиц. Делаю выборку и получаю 27 строк, сортирую их по 7 полю и оставляю только 14 строк, т.е. остаются строки только из тех таблиц из которых нужно делать сдедующие выборки. Т.к. выборка у меня в StringGrid, беру и присваиваю значения ячеек с именами таблиц, созданным переменным. Вот теперь эти переменные мне и нужно передать как входные параметры в процедуру, где эти входные параметры будут стоять на месте имени таблицы.

По большому счету, нужно из выборки из 27 таблиц определить с какими 14 в дальнейшем работать (это уже реализовано).
Теперь нужно сформировать запрос к этим 14 таблицам. Процедуру написать легко если изначально знать имена всех 14 таблиц, но набор будет меняться в зависимости от даты выборки 27 таблиц.

Не знаю, понятно ли объяснил.

Есть мыслишка как это в Delphi сделать, т.е. значеня переменных вставлять в Query запрос. 
PM MAIL   Вверх
Deniz
Дата 28.5.2009, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Цитата(Alkor135 @  27.5.2009,  22:26 Найти цитируемый пост)
Не знаю, понятно ли объяснил.
я не понял  smile 
Посмотрев на код типа
Код
while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
понятно, что SQL не знаешь.
Если задать дату, больше которой нет в таблице, будет как в анекдоте: "Ну у Вас и запросы - сказала база данных и повисла."
Это реализовывается 1 запросом:
Код
SELECT min(da) FROM audcad WHERE da >= :p_input_date_min into :p_input_date_min;
аналогично для времени и для max.
Опять же зачем хранить отдельно date и time, есть же timestamp?

Это сообщение отредактировал(а) Deniz - 28.5.2009, 09:00


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Alkor135
Дата 28.5.2009, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Deniz @ 28.5.2009,  08:33)
Цитата(Alkor135 @  27.5.2009,  22:26 Найти цитируемый пост)
Не знаю, понятно ли объяснил.
я не понял  smile 
Посмотрев на код типа
Код
while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
понятно, что SQL не знаешь.
Если задать дату, больше которой нет в таблице, будет как в анекдоте: "Ну у Вас и запросы - сказала база данных и повисла."
Это реализовывается 1 запросом:
Код
SELECT min(da) FROM audcad WHERE da >= :p_input_date_min into :p_input_date_min;
аналогично для времени и для max.
Опять же зачем хранить отдельно date и time, есть же timestamp?

То, что я только начал изучать SQL - это правда.
А вот то, что я не пробовал min и max - это не правда.
У меня сделано 27 вот таких поцедуд (к каждой таблице):
Код

CREATE PROCEDURE AUDCAD_PROCEDURE_RANGE (
    p_input_date date)
returns (
    p_pair char(6),
    p_da_min date,
    p_ti_min time,
    p_da_max date,
    p_ti_max time,
    p_op numeric(6,5),
    p_cl numeric(6,5),
    p_point numeric(6,1),
    p_point_mod numeric(6,1))
as
begin
/******************************************************************************/
/*                 Расчет AUDCAD для таблицы ранжирования                     */
/******************************************************************************/
   p_pair = 'AUDCAD';
/* Расчет минимальной даты в предыдущей неделе от выбранной даты */
  SELECT MIN(da)
  FROM audcad
  WHERE (EXTRACT (week from da))=EXTRACT (week from cast (:p_input_date as date)-7) AND
        (extract (year from da))=EXTRACT (YEAR from cast (:p_input_date as date)-7)
  INTO :p_da_min;

  SELECT MIN(ti)
  FROM audcad
  WHERE da = :p_da_min
  INTO :p_ti_min;

  SELECT MAX(da)
  FROM audcad
  WHERE (EXTRACT (week from da))=EXTRACT (week from cast (:p_input_date as date)-7) and
        (extract (year from da))=EXTRACT (YEAR from cast (:p_input_date as date)-7)
  INTO :p_da_max;

  SELECT MAX(ti)
  FROM audcad
  WHERE da = :p_da_max
  INTO :p_ti_max;

  SELECT op
  FROM audcad
  where (da = :p_da_min and ti = :p_ti_min)
  into :P_OP;

  SELECT cl
  FROM audcad
  where (da = :p_da_max and ti = :p_ti_max)
  into :p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end


И она, которая получает результат из всех 27:
Код

CREATE PROCEDURE SVOD_PROCEDURE_RANGE (
    p_input_date date)
returns (
    p_pair char(6),
    p_da_min date,
    p_ti_min time,
    p_da_max date,
    p_ti_max time,
    p_op numeric(8,5),
    p_cl numeric(8,5),
    p_point numeric(6,1),
    p_point_mod numeric(6,1))
as
begin
  execute procedure audcad_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure audchf_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod);
  suspend;

  execute procedure audjpy_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure audnzd_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure audusd_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure cadchf_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure cadjpy_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure chfjpy_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure euraud_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure eurcad_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure eurchf_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure eurgbp_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure eurjpy_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;
  /* --------- */
  execute procedure eurnzd_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure eurusd_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure gbpaud_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure gbpcad_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure gbpchf_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure gbpjpy_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure gbpusd_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure nzdcad_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure nzdchf_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure nzdjpy_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure nzdusd_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure usdcad_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure usdchf_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;

  execute procedure usdjpy_procedure_range(:P_INPUT_DATE)
    returning_values (:p_pair, :P_DA_MIN, :P_TI_MIN, :P_DA_MAX, :P_TI_MAX, :P_OP, :P_CL, :P_POINT, :p_point_mod); /**/
  suspend;
end


Так вок: сейчас у меня все прекрасно работает и сводную таблицу я получаю за 3 секунды.
Когда пользовался min и max, сводная таблица получалась за 40 секунд.
Поэтому я отказался от использования min и max.
PM MAIL   Вверх
Alkor135
Дата 28.5.2009, 10:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Ну вот, вспомнил Deniz анекдот, у меня прога и повисла.
Вот такую хранимую процедуру в БД:
Код

SET TERM ^ ;

CREATE OR ALTER PROCEDURE AUDCAD_PROC_END (
    p_input_date_min date,
    p_input_time_min time,
    p_input_date_max date,
    p_input_time_max time)
returns (
    p_pair char(6),
    p_da_min date,
    p_ti_min time,
    p_op numeric(6,5),
    p_da_max date,
    p_ti_max time,
    p_cl numeric(6,5),
    p_point integer,
    p_point_mod integer)
as
begin
  p_pair = 'AUDCAD';

  /* Если даты не существует, то берем следующую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
  /* Если время нужной даты не существует, то берем следующее время (в цикле) */
  p_ti_min = P_INPUT_TIME_MIN;
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_min) and ti = :p_ti_min))  do
    p_ti_min = p_ti_min + 1;
  /* Если даты не существует, то берем предыдущую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_max))  do
    p_input_date_max = p_input_date_max - 1;
  /* Если время нужной даты не существует, то берем предыдущее время (в цикле) */
  p_ti_max = P_INPUT_TIME_MAX;
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_max) and ti = :p_ti_max))  do
    p_ti_max = p_ti_max - 1;

  SELECT da, ti, op
  FROM audcad
  WHERE (da = :p_input_date_min and ti = :p_ti_min)
  INTO p_da_min, p_ti_min, p_op;

  SELECT da, ti, cl
  FROM audcad
  WHERE (da = :p_input_date_max and ti = :p_ti_max)
  INTO p_da_max, p_ti_max, p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end^

SET TERM ; ^

GRANT SELECT ON AUDCAD TO PROCEDURE AUDCAD_PROC_END;

GRANT EXECUTE ON PROCEDURE AUDCAD_PROC_END TO SYSDBA;


при этом все прекрасно работает 
user posted image

Я загружаю в StringGrid вот такой процедурой из Delphi:
Код

// Процедура получения конечной таблицы
procedure TForm1.SVOD_END();
var
  i : Integer;
  P_INPUT_DATE_MIN, P_INPUT_DATE_MAX : String;
  P_INPUT_TIME_MIN, P_INPUT_TIME_MAX : String;
begin
  P_INPUT_DATE_MIN := '02.03.2009';
  P_INPUT_TIME_MIN := '00:00';
  P_INPUT_DATE_MAX := '08.03.2009';
  P_INPUT_TIME_MAX := '23:59';

  P_1 := 'AUDCAD';
  //P_2 := 'AUDCHF';

  i := 1;
  {while i<>2 do
    begin  IBQuery1.Active:=False; }
      IBQuery2.SQL.Clear;
      IBQuery2.SQL.ADD('SELECT p_pair, p_da_min, p_ti_min, p_op, p_da_max, p_ti_max, p_cl, p_point, p_point_mod');
      IBQuery2.SQL.ADD('FROM '+P_1+'_proc_end (:P0, :P1, :P2, :P3)');
      IBQuery2.Params.Items[0].AsString := P_INPUT_DATE_MIN;
      IBQuery2.Params.Items[1].AsString := P_INPUT_TIME_MIN;
      IBQuery2.Params.Items[2].AsString := P_INPUT_DATE_MAX;
      IBQuery2.Params.Items[3].AsString := P_INPUT_TIME_MAX;
      IBQuery2.Active:=True;

        StringGrid2.Cells[0,i] := IBQuery2.Fields.Fields[0].Value;
        StringGrid2.Cells[1,i] := IBQuery2.Fields.Fields[1].Value;
        StringGrid2.Cells[2,i] := IBQuery2.Fields.Fields[2].Value;
        StringGrid2.Cells[3,i] := IBQuery2.Fields.Fields[3].Value;
        StringGrid2.Cells[4,i] := IBQuery2.Fields.Fields[4].Value;
        StringGrid2.Cells[5,i] := IBQuery2.Fields.Fields[5].Value;
        StringGrid2.Cells[6,i] := IBQuery2.Fields.Fields[6].Value;
        StringGrid2.Cells[7,i] := IBQuery2.Fields.Fields[7].Value;
        StringGrid2.Cells[8,i] := IBQuery2.Fields.Fields[8].Value;
    {    IBQuery1.Next();
        StringGrid2.RowCount := i+1;
        i := i+1;
    end;     }
  //SORT(); // Сортирую
end;

И прога виснет.
Может кто может подсказать, где я ошибся?

Это сообщение отредактировал(а) Alkor135 - 28.5.2009, 11:25
PM MAIL   Вверх
Gluttton
Дата 28.5.2009, 10:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 7
Всего: 54



Цитата

И прога виснет.

Сколько по времени выполняется процедура в IBExpert'е?
И скольк по времени программа находиться в "подвешеном" состоянии?
Как вариант диагноз может быть такой:
Поскольку обращение к БД не вынесено в отдельный поток и выполняется за ощутимое (т.е. 1, 2 и более секунд) время, то пользовательский интерфейс клиентской (той которая обращается к БД) программы "подвисает" и приложение "Не отвечает". Но при этом не факт, что оно не работает.

Сам с таким столкнулся и пришлось запрос к БД выносить в отдельный процес - жуть...


--------------------
Слава Україні!
PM MAIL   Вверх
Alkor135
Дата 28.5.2009, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Gluttton @ 28.5.2009,  10:57)
Цитата

И прога виснет.

Сколько по времени выполняется процедура в IBExpert'е?
И скольк по времени программа находиться в "подвешеном" состоянии?
Как вариант диагноз может быть такой:
Поскольку обращение к БД не вынесено в отдельный поток и выполняется за ощутимое (т.е. 1, 2 и более секунд) время, то пользовательский интерфейс клиентской (той которая обращается к БД) программы "подвисает" и приложение "Не отвечает". Но при этом не факт, что оно не работает.

Сам с таким столкнулся и пришлось запрос к БД выносить в отдельный процес - жуть...

В IBExpert процедура обрабатывается за 1-2 секунды.
Когда вызываю из Delphi, то 5 минут ждал, потом надоело и закрыл. Отсюда и вынес вердикт, что она повесилась.
А как вынести в отдельный поток обращение к базе?

Ой, нашел свою ошибочку.  smile 
Орфография хромает.  smile 

Это сообщение отредактировал(а) Alkor135 - 28.5.2009, 11:26
PM MAIL   Вверх
Gluttton
Дата 28.5.2009, 11:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 7
Всего: 54



Цитата

В IBExpert процедура обрабатывается за 1-2 секунды.
Когда вызываю из Delphi, то 5 минут ждал

При одинаковых входящих параметрах (извиняюсь за недоверчивость smile )? 
А вообще к БД обращение проходить нормально, т.е. любой другой запрос выполняется или это пока первый?

Цитата

А как вынести в отдельный поток обращение к базе?

Я пишу на CLI\C++ (не советую связываться, если под .NET, то лучше С# сразу брать и не мучаться smile ), так там (в .New Framwork) есть такой компонент backGroundWorker, который в себе это всё дело инкапсулирует... А если нет, то тогда юзать Thread...


--------------------
Слава Україні!
PM MAIL   Вверх
Alkor135
Дата 28.5.2009, 11:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Gluttton @ 28.5.2009,  11:28)
Цитата

В IBExpert процедура обрабатывается за 1-2 секунды.
Когда вызываю из Delphi, то 5 минут ждал

При одинаковых входящих параметрах (извиняюсь за недоверчивость smile )? 
А вообще к БД обращение проходить нормально, т.е. любой другой запрос выполняется или это пока первый?

Цитата

А как вынести в отдельный поток обращение к базе?

Я пишу на CLI\C++ (не советую связываться, если под .NET, то лучше С# сразу брать и не мучаться smile ), так там (в .New Framwork) есть такой компонент backGroundWorker, который в себе это всё дело инкапсулирует... А если нет, то тогда юзать Thread...

Вот-вот, во входящие параметры закралась ошибочка, но теперь то я пост подправил и ее не видно.   smile 

А вообще это мой первый проект по программированию как в Delphi так и в SQL (FireBird).
Delphi мне показался проще чем С++. До сих пор вехать не могу, чтож за классы там такие.
К томуже, примеров для Delphi нашел больше.
Мне вообще советовали на Java писать, говорят кросплатформенная штука, за ней будующее.
PM MAIL   Вверх
Deniz
Дата 28.5.2009, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Цитата(Alkor135 @  28.5.2009,  12:17 Найти цитируемый пост)
Так вок: сейчас у меня все прекрасно работает и сводную таблицу я получаю за 3 секунды.
Когда пользовался min и max, сводная таблица получалась за 40 секунд.
Поэтому я отказался от использования min и max. 
не верю (с)
Сравни 2 кода на быстродействие (сделай 2 тестовые процедуры):
Код
while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
и
Код
SELECT min(da) FROM audcad WHERE da >= :p_input_date_min into :p_input_date_min;

причем, в первом случае чем дальше нужная дата тем дольше будет работать.
А во втором время практически не изменится. Наличие индекса по дате может улучшить оба варианта.
PS: К тому же первый вариант некорректен, есть возможность бесконечного(пока размер даты не кончится) цикла.


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Alkor135
Дата 28.5.2009, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Deniz @ 28.5.2009,  15:02)
Цитата(Alkor135 @  28.5.2009,  12:17 Найти цитируемый пост)
Так вок: сейчас у меня все прекрасно работает и сводную таблицу я получаю за 3 секунды.
Когда пользовался min и max, сводная таблица получалась за 40 секунд.
Поэтому я отказался от использования min и max. 
не верю (с)
Сравни 2 кода на быстродействие (сделай 2 тестовые процедуры):
Код
while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
и
Код
SELECT min(da) FROM audcad WHERE da >= :p_input_date_min into :p_input_date_min;

причем, в первом случае чем дальше нужная дата тем дольше будет работать.
А во втором время практически не изменится. Наличие индекса по дате может улучшить оба варианта.
PS: К тому же первый вариант некорректен, есть возможность бесконечного(пока размер даты не кончится) цикла.

А FireBird, где-нибудь показывает за какое время он выполнил процедуру?
Я сравнил визуально, моя выполняется за 2 сек., твоя за 3 сек., но я могу быть субективен.

Зато очень сильно отличаюся по скорости две моих других процедуры.
Та что за 2 сек.
Код

SET TERM ^ ;

CREATE OR ALTER PROCEDURE AUDCAD_PROCEDURE (
    p_input_date_min date,
    p_input_date_max date)
returns (
    p_pair char(6),
    p_da_min date,
    p_ti_min time,
    p_op numeric(6,5),
    p_da_max date,
    p_ti_max time,
    p_cl numeric(6,5),
    p_point numeric(6,1),
    p_point_mod numeric(6,1))
as
begin
/******************************************************************************/
/*                 Расчет AUDCAD для таблицы ранжирования                     */
/******************************************************************************/
  p_pair = 'AUDCAD';

  /* Если даты не существует, то берем следующую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
  /* Если время нужной даты не существует, то берем следующее время (в цикле) */
  p_ti_min = '00:00';
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_min) and ti = :p_ti_min))  do
    p_ti_min = p_ti_min + 1;

  /* Если даты не существует, то берем предыдущую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_max))  do
    p_input_date_max = p_input_date_max - 1;
  /* Если время нужной даты не существует, то берем предыдущее время (в цикле) */
  p_ti_max = '23:59';
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_max) and ti = :p_ti_max))  do
    p_ti_max = p_ti_max - 1;

  SELECT da, ti, op
  FROM audcad
  WHERE (da = :p_input_date_min and ti = :p_ti_min)
  INTO p_da_min, p_ti_min, p_op;

  SELECT da, ti, cl
  FROM audcad
  WHERE (da = :p_input_date_max and ti = :p_ti_max)
  INTO p_da_max, p_ti_max, p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end^

SET TERM ; ^

GRANT SELECT ON AUDCAD TO PROCEDURE AUDCAD_PROCEDURE;

GRANT EXECUTE ON PROCEDURE AUDCAD_PROCEDURE TO PROCEDURE SVOD_PROCEDURE;
GRANT EXECUTE ON PROCEDURE AUDCAD_PROCEDURE TO SYSDBA;


Вторая с min и max выполняется почти 2 мин.:
Код

SET TERM ^ ;

CREATE OR ALTER PROCEDURE AUDCAD_PROCEDURE_RANGE (
    p_input_date date)
returns (
    p_pair char(6),
    p_da_min date,
    p_ti_min time,
    p_da_max date,
    p_ti_max time,
    p_op numeric(6,5),
    p_cl numeric(6,5),
    p_point numeric(6,1),
    p_point_mod numeric(6,1))
as
begin
/******************************************************************************/
/*                 Расчет AUDCAD для таблицы ранжирования                     */
/******************************************************************************/
   p_pair = 'AUDCAD';
/* Расчет минимальной даты в предыдущей неделе от выбранной даты */
  SELECT MIN(da)
  FROM audcad
  WHERE (EXTRACT (week from da))=EXTRACT (week from cast (:p_input_date as date)-7) AND
        (extract (year from da))=EXTRACT (YEAR from cast (:p_input_date as date)-7)
  INTO :p_da_min;

  SELECT MIN(ti)
  FROM audcad
  WHERE da = :p_da_min
  INTO :p_ti_min;

  SELECT MAX(da)
  FROM audcad
  WHERE (EXTRACT (week from da))=EXTRACT (week from cast (:p_input_date as date)-7) and
        (extract (year from da))=EXTRACT (YEAR from cast (:p_input_date as date)-7)
  INTO :p_da_max;

  SELECT MAX(ti)
  FROM audcad
  WHERE da = :p_da_max
  INTO :p_ti_max;

  SELECT op
  FROM audcad
  where (da = :p_da_min and ti = :p_ti_min)
  into :P_OP;

  SELECT cl
  FROM audcad
  where (da = :p_da_max and ti = :p_ti_max)
  into :p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end^

SET TERM ; ^

GRANT SELECT ON AUDCAD TO PROCEDURE AUDCAD_PROCEDURE_RANGE;

GRANT EXECUTE ON PROCEDURE AUDCAD_PROCEDURE_RANGE TO SYSDBA;


Хотя эти процедуры не совсем равнозначны. У первой два входных параметра, а вторая один входной обсчитывает и делает два параметра внутри себя.
Может действительно скорость выполнения не от использования min и max зависит? 
Тогда подскажите отчего она такая разная?
Кстати все таблицы у меня проиндексированы по двум полям (по дате и по времени).


Это сообщение отредактировал(а) Alkor135 - 28.5.2009, 17:06
PM MAIL   Вверх
Gluttton
Дата 28.5.2009, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 7
Всего: 54



Цитата

А FireBird, где-нибудь показывает за какое время он выполнил процедуру?


Ну здрасте, а скриншот ты с чего делал?! Не с IBExpert'а?!
Вот в нём при выполнении запроса в нижней части активного окна появляется Memo-поле, куда выводиться код ошибки, план запроса и время выполнения запроса! smile !


--------------------
Слава Україні!
PM MAIL   Вверх
Akella
Дата 28.5.2009, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Цитата(Alkor135 @  28.5.2009,  17:03 Найти цитируемый пост)
А FireBird, где-нибудь показывает за какое время он выполнил процедуру?

а как FireBird ПОКАЖЕТ?
PM MAIL   Вверх
Deniz
Дата 29.5.2009, 06:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Цитата(Alkor135 @  28.5.2009,  20:03 Найти цитируемый пост)
Зато очень сильно отличаюся по скорости две моих других процедуры.

Цитата(Alkor135 @  28.5.2009,  20:03 Найти цитируемый пост)
Хотя эти процедуры не совсем равнозначны.
честно говоря подробно не разбирался, но такое ощущение, что они еще и результат разный выдают.
Та, что с min ищет минимальную дату на прошлой неделе, а другая "смотрит" вперед по датам.
Даже твой "страшный" select с extract'ом можно оптимизировать до неузнаваемости. Например, сначала вычислить период прошлой недели (дата начала и дата окончания недели), от переданной даты. А потом 
Код
select ... from ... where da between :d1 and :d2
использование индекса гарантировано, в отличии от where extract, там индекс по дате не используется.
Цитата(Alkor135 @  28.5.2009,  20:03 Найти цитируемый пост)
Может действительно скорость выполнения не от использования min и max зависит? 
Тогда подскажите отчего она такая разная?
каждый запрос в процедуре нужно оптимизировать.
Подсказка, если удается добиться использования уникального индекса, скорость возрастает на порядки, неуникальный хороший индекс тоже поможет.
А вообще читай www.ibase.ru
и вот например FAQ: оптимизация запросов


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Alkor135
Дата 29.5.2009, 07:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Gluttton @ 28.5.2009,  17:14)
Цитата

А FireBird, где-нибудь показывает за какое время он выполнил процедуру?


Ну здрасте, а скриншот ты с чего делал?! Не с IBExpert'а?!
Вот в нём при выполнении запроса в нижней части активного окна появляется Memo-поле, куда выводиться код ошибки, план запроса и время выполнения запроса! smile !

Извиняйте, ребята. Я еще совсем мало с IBExpert работаю.
Вот смотрю на экран и не вижу этого memo поля.
Ткните меня носом, где оно должно быть?
А может я что-то в настройках не включил?
user posted image

PM MAIL   Вверх
Alkor135
Дата 29.5.2009, 07:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Akella @ 28.5.2009,  17:31)
Цитата(Alkor135 @  28.5.2009,  17:03 Найти цитируемый пост)
А FireBird, где-нибудь показывает за какое время он выполнил процедуру?

а как FireBird ПОКАЖЕТ?

Akella, действительно я глупость написал. 
А думал о IBExpert.
PM MAIL   Вверх
Gluttton
Дата 29.5.2009, 07:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 7
Всего: 54



Цитата

Извиняйте, ребята. 

Да ради Бога smile ...
Цитата

Вот смотрю на экран и не вижу этого memo поля.
Ткните меня носом, где оно должно быть?

Да... Я тоже удивился, что его нету... Что бы появилось нужно нажать на кнопочку "Edit" (после выполнения процедуры) и искать это поле внизу.
А ещё можно выполнять процедуры несколько иначе. Создать новый скрипт (кнопочка обведена желтым) вставить в него код вызова процедуры и выполнить.

И ещё... У Вас нет тригеров и генераторов - это хоть и возможно, но весьма подозритьельно, а вот то что нет доменов - это однозначно, не то что бы не правильно, а скорее не оптимально с точки зрения удобства работы с кодом.

user posted image

Это сообщение отредактировал(а) Gluttton - 29.5.2009, 07:50


--------------------
Слава Україні!
PM MAIL   Вверх
Alkor135
Дата 29.5.2009, 07:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Deniz, спасибо за мысли и за ссылки. 
Поразбираюсь на досуге. smile
PM MAIL   Вверх
Deniz
Дата 29.5.2009, 07:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Цитата(Alkor135 @  29.5.2009,  10:07 Найти цитируемый пост)
Вот смотрю на экран и не вижу этого memo поля.
Ткните меня носом, где оно должно быть?
читаем внимательнее
Цитата(Gluttton @  28.5.2009,  20:14 Найти цитируемый пост)
Вот в нём при выполнении запроса в нижней части активного окна появляется Memo-поле...
именно запроса, а не процедуры.


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Alkor135
Дата 29.5.2009, 07:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Gluttton, триггеров действительно нет, но думаю они и не нужны мне. 
Ведь событий у таблиц не будет, мне не нужны в них изменения.

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

Насчет Доменов, вообще не понял, что это за зверь и с чем его едят?

Попробовал после выполнения процедуры переключиться на вкладку Edit, но поля со временем выполнения процедуры опять не нашел:
user posted image

Через SQL редактор, тестировать на скорость каждый запрос в процедуре, мне кажется долго, но если необходимость возникнет, то сделаю.
Спасибо за подсказку.
PM MAIL   Вверх
Alkor135
Дата 29.5.2009, 08:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Deniz, да, теперь я понял, что только в запрсах можно посмотреть время выполнения.
А вот было бы в процедурах, было бы замечательно.
Вот как организовать запрос у:

  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;

PM MAIL   Вверх
Gluttton
Дата 29.5.2009, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 7
Всего: 54



 smile 
Это конечно не относиться к теме, но раз сказал "А", то говорю и "В".
Отсутствие тригеров и генераторов - признак того, что в БД отсутствуют поля AUTOINCREMENT в нотации Access, которые приверженцы сурогатных ключей используют в качестве первичных ключей. Но это совершенно не догма.
Домены, не знаю как это будет правильно, но если своими словами, то это именованый пользовательский тип данных, например:
определив однажды домен:
Код

CREATE DOMAIN NAME      AS VARCHAR(200);
CREATE DOMAIN ID        AS BIGINT             NOT NULL;
CREATE DOMAIN INFO      AS VARCHAR(900);


можно его многократно использовать в дальнейшем (при создании таблиц):
Код

CREATE TABLE TYPE
(
    ID          ID,
    ID_SCALE    ID,
    ID_GROUP    ID,
    CODE    CODE,
    NAME        NAME,
    INFO        INFO
);


Цитата

А вот было бы в процедурах, было бы замечательно.


Ну дык
Цитата

А ещё можно выполнять процедуры несколько иначе. 
Создать новый скрипт (кнопочка обведена желтым) вставить в него код вызова процедуры и выполнить.


Это сообщение отредактировал(а) Gluttton - 29.5.2009, 09:01


--------------------
Слава Україні!
PM MAIL   Вверх
Akella
Дата 29.5.2009, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Alkor135, в настройках эксперт включи MDI интерфейс.
меню Настройки->Настройки среды-> слева вверху Тип интерфейса->многодокументальный.
Нажми Ок.
Разверни на всю правое окно. 
user posted image
красным я обвёл, как посмотреть параметры исполненного запроса: план, сколько памяти, время...
PM MAIL   Вверх
Deniz
Дата 29.5.2009, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Так же можно просто сделать select из процедуры
Код
select * from proc_name(param1, param2, ..., paramN)

Согласен с Gluttton, отсутствие доменов, генераторов и триггеров настораживает.


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Alkor135
Дата 29.5.2009, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Gluttton, я так понял, что триггеры и генераторы мне не нужны. 
Зачем мне суррогатные ключи, скорости они не прибавят. smile

Спасибо за просвящение с Доменами, теперь их использовать мне тоже не имеет смысла, ведь таблицы уже созданы.

Добавлено @ 12:52
Akella, спасибо за подсказки по настройке интерфейса. Оказывается IBExpert и по русски может smile .

Akella, Gluttton, Deniz, попробовал я выполнить процедуру из SQL редактора.
Все равно время выполнения не показывает.
user posted image

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

Это сообщение отредактировал(а) Alkor135 - 29.5.2009, 12:54
PM MAIL   Вверх
Alkor135
Дата 29.5.2009, 14:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Я свой вопрос решил.
Правда не имя таблицы загонял как входящий параметр,
а вклеивал начало вызываемой процедуры(через Query) из Delphi.

Код

  i := 1;
  while i<>15 do
    begin
      if i=1 then P := P_1;
      if i=2 then P := P_2;
      if i=3 then P := P_3;
      if i=4 then P := P_4;
      if i=5 then P := P_5;
      if i=6 then P := P_6;
      if i=7 then P := P_7;
      if i=8 then P := P_8;
      if i=9 then P := P_9;
      if i=10 then P := P_10;
      if i=11 then P := P_11;
      if i=12 then P := P_12;
      if i=13 then P := P_13;
      if i=14 then P := P_14;

      IBQuery2.Active:=False;
      IBQuery2.SQL.Clear;
      IBQuery2.SQL.ADD('SELECT p_pair, p_da_min, p_ti_min, p_op, p_da_max, p_ti_max, p_cl, p_point, p_point_mod');
      IBQuery2.SQL.ADD('FROM '+P+'_PROC_END (:P0, :P1, :P2, :P3)');
      IBQuery2.Params.Items[0].AsString := P_INPUT_DATE_MIN;
      IBQuery2.Params.Items[1].AsString := P_INPUT_TIME_MIN;
      IBQuery2.Params.Items[2].AsString := P_INPUT_DATE_MAX;
      IBQuery2.Params.Items[3].AsString := P_INPUT_TIME_MAX;
      IBQuery2.Active:=True;

        StringGrid2.Cells[0,i] := IBQuery2.Fields.Fields[0].Value;
        StringGrid2.Cells[1,i] := IBQuery2.Fields.Fields[1].Value;
        StringGrid2.Cells[2,i] := IBQuery2.Fields.Fields[2].Value;
        StringGrid2.Cells[3,i] := IBQuery2.Fields.Fields[3].Value;
        StringGrid2.Cells[4,i] := IBQuery2.Fields.Fields[4].Value;
        StringGrid2.Cells[5,i] := IBQuery2.Fields.Fields[5].Value;
        StringGrid2.Cells[6,i] := IBQuery2.Fields.Fields[6].Value;
        StringGrid2.Cells[7,i] := IBQuery2.Fields.Fields[7].Value;
        StringGrid2.Cells[8,i] := IBQuery2.Fields.Fields[8].Value;
        IBQuery1.Next();
        StringGrid2.RowCount := i+1;
        i := i+1;
    end;


Всем Большое Спасибо!!!
По Вашим советам позже еще пооптимизирую SQL код.
Всем бы поставил плюсики, но говорят у меня еще постов для этого мало :( .

Это сообщение отредактировал(а) Alkor135 - 29.5.2009, 14:19
PM MAIL   Вверх
Akella
Дата 29.5.2009, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Цитата(Alkor135 @  29.5.2009,  12:42 Найти цитируемый пост)
А может это ограничения персональной версии. 

Первый раз слышу про персональную версию.
Скачай полную
http://forum.vingrad.ru/index.php?showtopi...t&p=1866918
PM MAIL   Вверх
Alkor135
Дата 29.5.2009, 23:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Akella @ 29.5.2009,  21:46)
Цитата(Alkor135 @  29.5.2009,  12:42 Найти цитируемый пост)
А может это ограничения персональной версии. 

Первый раз слышу про персональную версию.
Скачай полную
http://forum.vingrad.ru/index.php?showtopi...t&p=1866918

Да вроде у меня официальная версия.
user posted image

А вот эти функции не работают:
user posted image

Говорит:
user posted image

А если другую версию качать по ссылке, то файл называется setup_trial.exe  ?
PM MAIL   Вверх
Akella
Дата 30.5.2009, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Цитата(Alkor135 @  29.5.2009,  23:56 Найти цитируемый пост)
А если другую версию качать по ссылке, то файл называется setup_trial.exe  ? 

Да.
PM MAIL   Вверх
Alkor135
Дата 30.5.2009, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 42
Регистрация: 5.4.2009

Репутация: нет
Всего: нет



Цитата(Akella @ 30.5.2009,  00:20)
Цитата(Alkor135 @  29.5.2009,  23:56 Найти цитируемый пост)
А если другую версию качать по ссылке, то файл называется setup_trial.exe  ? 

Да.

Ой спасибо, Akella!

Теперь у меня время выполнения показывает.
 Сравнил я скорости выполнения запросов с min и без него.
Я оказался прав. Без использования min запрос обрабатывается быстрее.

Без min:
user posted image

C использованием min:
user posted image

Вот код процедуры без использования min:
Код

egin
/******************************************************************************/
/*                 Расчет AUDCAD для таблицы ранжирования                     */
/******************************************************************************/
  p_pair = 'AUDCAD';

  /* Если даты не существует, то берем следующую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_min))  do
    p_input_date_min = p_input_date_min + 1;
  /* Если время нужной даты не существует, то берем следующее время (в цикле) */
  p_ti_min = '00:00';
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_min) and ti = :p_ti_min))  do
    p_ti_min = p_ti_min + 1;

  /* Если даты не существует, то берем предыдущую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_max))  do
    p_input_date_max = p_input_date_max - 1;
  /* Если время нужной даты не существует, то берем предыдущее время (в цикле) */
  p_ti_max = '23:59';
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_max) and ti = :p_ti_max))  do
    p_ti_max = p_ti_max - 1;

  SELECT da, ti, op
  FROM audcad
  WHERE (da = :p_input_date_min and ti = :p_ti_min)
  INTO p_da_min, p_ti_min, p_op;

  SELECT da, ti, cl
  FROM audcad
  WHERE (da = :p_input_date_max and ti = :p_ti_max)
  INTO p_da_max, p_ti_max, p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end


Вот код процедуры с использованием min:
Код

begin
/******************************************************************************/
/*                 Расчет AUDCAD для таблицы ранжирования                     */
/******************************************************************************/
  p_pair = 'AUDCAD';

  /* Если даты не существует, то берем следующую дату (в цикле) */
  SELECT min(da) FROM audcad WHERE da >= :p_input_date_min into :p_input_date_min;
  /* Если время нужной даты не существует, то берем следующее время (в цикле) */
  p_ti_min = '00:00';
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_min) and ti = :p_ti_min))  do
    p_ti_min = p_ti_min + 1;

  /* Если даты не существует, то берем предыдущую дату (в цикле) */
  while (NOT exists (SELECT da FROM audcad WHERE da = :p_input_date_max))  do
    p_input_date_max = p_input_date_max - 1;
  /* Если время нужной даты не существует, то берем предыдущее время (в цикле) */
  p_ti_max = '23:59';
  while (NOT exists (SELECT ti FROM audcad WHERE (da = :p_input_date_max) and ti = :p_ti_max))  do
    p_ti_max = p_ti_max - 1;

  SELECT da, ti, op
  FROM audcad
  WHERE (da = :p_input_date_min and ti = :p_ti_min)
  INTO p_da_min, p_ti_min, p_op;

  SELECT da, ti, cl
  FROM audcad
  WHERE (da = :p_input_date_max and ti = :p_ti_max)
  INTO p_da_max, p_ti_max, p_cl;

  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;

  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;

  suspend;
end


Может конечно, я что-то сделал необъективно. Предлагаайте проведу еще тест, чтобы выяснить действительно ли использование min и max увеличивает время исполнения запроса.
PM MAIL   Вверх
Deniz
Дата 1.6.2009, 06:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1251
Регистрация: 16.10.2004
Где: Новый Уренгой

Репутация: 22
Всего: 44



Alkor135попробуй во 2 процедуре все перевести на min/max
Код
begin
/******************************************************************************/
/*                 Расчет AUDCAD для таблицы ранжирования                     */
/******************************************************************************/
  p_pair = 'AUDCAD';
  /* Если даты не существует, то берем следующую дату (в цикле) */
  SELECT min(da) FROM audcad WHERE da >= :p_input_date_min into :p_input_date_min;
  /* Если время нужной даты не существует, то берем следующее время (в цикле) */
  p_ti_min = '00:00';
  SELECT min(ti) FROM audcad WHERE da = :p_input_date_min into :p_ti_min;

  /* Если даты не существует, то берем предыдущую дату (в цикле) */
  SELECT max(da) FROM audcad WHERE da <= :p_input_date_max into :p_input_date_max;
  /* Если время нужной даты не существует, то берем предыдущее время (в цикле) */
  p_ti_max = '23:59';
  SELECT max(ti) FROM audcad WHERE da = :p_input_date_max into :p_ti_max;

  SELECT da, ti, op
  FROM audcad
  WHERE (da = :p_input_date_min and ti = :p_ti_min)
  INTO p_da_min, p_ti_min, p_op;
  SELECT da, ti, cl
  FROM audcad
  WHERE (da = :p_input_date_max and ti = :p_ti_max)
  INTO p_da_max, p_ti_max, p_cl;
  /* Разница в пунктах */
  p_point = (p_op - p_cl)* 100000;
  /* Разница в пунктах по модулю */
  if (p_point<0) THEN
    p_point_mod = p_point*(-1);
    else p_point_mod = p_point;
  suspend;
end
запусти обе процедуры по несколько раз.
И покажи какие индексы есть на таблицу audcad.


--------------------
"Для того чтобы сделать шаг вперед, достаточно пинка сзади" (с)
PM ICQ   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Interbase"
Alex

Обязательно указание:

1. Версию InterBase (Firebird, Yaffil)

2. Способа доступа (ADO, BDE, IBX и т.д.)

  • КАК ПРАВИЛЬНО ОФОРМИТЬ КОД - ЗДЕСЬ
  • КАК ПРАВИЛЬНО УКАЗАТЬ ТЕКСТ ОШИБКИ - ЗДЕСЬ
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С Уважением, Akella.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Firebird, Interbase | Следующая тема »


 




[ Время генерации скрипта: 0.0935 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.