Нехорошие люди в таблице

Модераторы: kdv, CyberMax

Ответить
Solo
Сообщения: 108
Зарегистрирован: 18 апр 2005, 04:05

Нехорошие люди в таблице

Сообщение Solo » 28 сен 2007, 10:30

В таблице попадаются нехорошие люди. Которые не должны попасть в файл выгрузки. У них есть особые номера (начинаются на тройку). Так что определить их несложно: LIKE '3______'. А вот при выгрузке надо подставлять вместо нехороших людей - хороших. Причем надо, чтобы пол совпадал. Но это тоже несложно. И чтобы разница в возрасте была как можно меньше. Причем в разных выгрузках подставы должны быть одни и те же. Для этой цели я добавил поле "REDIR". У хороших людей оно пустое, у нехороших - содержит ID того, который пойдет на замену.
Триггер "после инсерта" проверяет LIKE '3______', и дальше он (или запускаемая триггером SP) должны выбрать хорошего, еще не выбранного, с тем же полом... Но это еще ладно. Главное - при всех этих условиях выбрать еще и ближайшего по возрасту.

Вот, прежде чем городить огород, решил спросить :roll:

Solo
Сообщения: 108
Зарегистрирован: 18 апр 2005, 04:05

Сообщение Solo » 28 сен 2007, 10:35

Да, наверное, уже выбранных можно будет тоже в поле редиректа помечать нулем. Ведь 0 и null - это разные вещи.

Solo
Сообщения: 108
Зарегистрирован: 18 апр 2005, 04:05

Сообщение Solo » 01 окт 2007, 11:40

Вот наброски первые:

Код: Выделить всё

AS
begin
  /* Trigger text */
  if (new.ndoc like '3_____') then
  begin
    new.redir =
    (

    select distinct IID
    from insured
    where (extract(year from insured.dr))-(extract(year from new.dr)) =
            (
    select min(F_1) from (
    select (extract(year from insured.dr))-(extract(year from new.dr)) as F_1
            from insured
            )
            )
    );

  end
end
Так он, гад, кричит:
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Subselect illegal in this context.
Пробуем вынести всю эту бодягу в ХП, вроде компилируется. Нигде не могу найти функции абсолютной величины... Есть в FB что-то вроде "ABS"?

Slavik
Сообщения: 115
Зарегистрирован: 17 янв 2007, 11:52

Сообщение Slavik » 01 окт 2007, 12:31

Solo писал(а):Так он, гад, кричит:
Subselect illegal in this context.
Если мне память не изменяет, то в FB в операторе присваивания нельзя писать подзапросы. Для этого существует конструкция select ... into ... Хотя, может уже и изменилось что-то.
Solo писал(а):Есть в FB что-то вроде "ABS"?
Только в UDF-ках. Но есть case, а в FB2 ещё и iif

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 01 окт 2007, 14:31

Код: Выделить всё

new.redir = 
  (select first 1 IID
     from insured
     order by (case when insured.dr>new.dr then insured.dr-new.dr else new.dr-insured.dr end) desc
  );

Solo
Сообщения: 108
Зарегистрирован: 18 апр 2005, 04:05

Сообщение Solo » 01 окт 2007, 15:16

WildSery писал(а):

Код: Выделить всё

new.redir = 
  (select first 1 IID
     from insured
     order by (case when insured.dr>new.dr then insured.dr-new.dr else new.dr-insured.dr end) desc
  );
Блин, а я нагородил уже:

Код: Выделить всё

begin
  /* Procedure Text */

    for select IID
    from insured
    where
      IIF(
                ((extract(year from insured.dr))-(extract(year from :in_dr)))>0,
                ((extract(year from insured.dr))-(extract(year from :in_dr))),
                -((extract(year from insured.dr))-(extract(year from :in_dr)))
             )  =
            (
    select min( IIF(F_1>0, F_1, -F_1) )
                    from (

      select (extract(year from insured.dr))-(extract(year from :in_dr)) as F_1
            from insured
            )
            ) AND
              insured.w = :in_w /*the same wendor*/
              AND
              insured.redir = -1

    into :redir_id do begin
      suspend;
      exit;
  end
end
И кстати, вопреки всем ожиданиям сработало :roll: Slavik спасибо, я про IIF не знал...
Сейчас попробую покороче...

Solo
Сообщения: 108
Зарегистрирован: 18 апр 2005, 04:05

Сообщение Solo » 01 окт 2007, 15:25

WildSery писал(а):

Код: Выделить всё

new.redir = 
  (select first 1 IID
     from insured
     order by (case when insured.dr>new.dr then insured.dr-new.dr else new.dr-insured.dr end) desc
  );
Вот триггер (без использования вышеописанной процы)

Код: Выделить всё

AS
begin
  /* Trigger text ïðîâåðÿåì ïåðâóþ òðîéêó*/
  if ( (new.ndoc like '3_____') or (new.ncont = '1568') ) then
  begin
  /*  execute procedure pr_assign_redirect(new.w, new.dr) returning_values new.redir; */
    new.redir =
    (select first 1 IID
     from insured
     where insured.redir = -1 and
           insured.w = new.w
     order by (case
                when insured.dr > new.dr then insured.dr-new.dr
                else new.dr-insured.dr end) desc
  );

  end
end
Не покатил:
Column does not belong to referenced table.
Dynamic SQL Error.
SQL error code = -206.
Subselect illegal in this context.
Slavik был прав - не дает присваивать субселект :(

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 01 окт 2007, 15:42

А самому догадаться?
select first 1 IID from ... into new.redir;

Solo
Сообщения: 108
Зарегистрирован: 18 апр 2005, 04:05

Сообщение Solo » 01 окт 2007, 16:08

WildSery писал(а):А самому догадаться?
select first 1 IID from ... into new.redir;
:roll: Понедельник - трудный день

Спасибо принявшим участие...

Ответить