Оценка параметров на основе значений объекта с использованием триггера / процедуры - PullRequest
1 голос
/ 28 января 2011

У меня следующая проблема.В моем приложении пользователь создает игрового персонажа, используя специальную систему (Сила, Восприятие и т. Д. Со значениями от 1 до 10).При сохранении или после (при вызове процедуры) мне нужно посчитать статистику персонажа на основе значений СПЕЦИАЛЬНЫХ параметров.Как я могу это сделать ?Это схема отношений:

enter image description here

и вот код SQL:

create table Player (
  id_player numeric,
  player_name varchar2(50) not null,
  age decimal not null,
  strength decimal not null,
  perception decimal not null,
  endurance decimal not null,
  charisma decimal not null,
  inteligence decimal not null,
  agility decimal not null,
  luck decimal not null,
  caps decimal not null,
  statistics numeric,
  CONSTRAINT chk_s check (strength <= 10),
  CONSTRAINT chk_p check (perception <= 10),
  CONSTRAINT chk_e check (endurance <= 10),
  CONSTRAINT chk_c check (charisma <= 10),
  CONSTRAINT chk_i check (inteligence <= 10),
  CONSTRAINT chk_a check (agility <= 10),
  CONSTRAINT chk_l check (luck <= 10),
  CONSTRAINT unique_name UNIQUE (player_name),

  CONSTRAINT PLAYER_PK primary key (id_player)
);

create table Player_derived_statistics(
  id_statistics numeric,
  carry_weight decimal,
  hit_points decimal,
  radiation_resistance decimal,

  CONSTRAINT DERIVED_STATISTICS_PK primary key (id_statistics)
);

alter table Player add constraint PLAYER_DERIVED_STATISTICS_FK1 foreign key (statistics) references Player_derived_statistics (id_statistics);

и запрос, возвращающий все параметры:

SELECT p.strength, p.perception, p.endurance, p.charisma, p.inteligence, p.agility, p.luck
from player p inner join player_derived_statistics s on s.id_statistics = p.statistics;

Итак, в конце я хотел бы иметь возможность подсчитывать carry_weight, hit_points и radi_resistance для каждого игрока.Допустим, все формулы (player_parameter * 10) + 150.Что было бы лучше использовать: триггер или процедуру?


РЕДАКТИРОВАТЬ

Я пытаюсь использовать код из ответа, но я получаю ошибку Encountered the symbol "INNER" when expecting one of the following: ( ....

CREATE OR REPLACE PACKAGE pkg_player_stats AS
  FUNCTION get_derived_stats( p_id_player IN player.id_player%TYPE )
    RETURN derived_stats_rec
  IS
    l_stats_rec derived_stats_rec;
  BEGIN
    SELECT (p.strength*10)+150,
           (p.endurance*20)+150,
           ((p.endurance-1)*2)/100
      INTO l_stats_rec.carry_weight,
           l_stats_rec.hit_points,
           l_stats_rec.radiation_resistance
      FROM (
        SELECT p.strength,  
               p.endurance
          from player p inner join player_derived_statistics s on s.id_statistics = p.statistics);
    RETURN l_stats_rec;
  END get_derived_stats;
END;

Ответы [ 2 ]

0 голосов
/ 28 января 2011

Зачем вам две таблицы?Я бы выбрал либо

  • Единственную таблицу со всеми СПЕЦИАЛЬНЫМИ статистиками и представлением, которое вычисляет производную статистику (в вашем приложении вы бы запросили представление):

    CREATE VIEW player_v AS 
    SELECT p.strength, ..., /* all attributes */
           p.strength * 10 + 150 as carry_weight,
           p.endurance * 20 + 150 as hit_points,
           (p.endurance - 1) * 2 / 100 as radiation_resistance
      FROM player p
    
  • Одна таблица с производными столбцами, которую вы обновляете с помощью триггера:

    CREATE OR REPLACE TRIGGER player_ins_up_trg 
       BEFORE UPDATE OR INSERT ON player
       FOR EACH ROW
    BEGIN
       :new.carry_weight := :new.strength * 10 + 150;
       :new.hit_points := :new.endurance * 20 + 150;
       :new.radiation_resistance := (:new.endurance - 1) * 2 / 100;
    END;
    
  • Если вы используете Oracle 11, вы также можете использовать виртуальный столбец :

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

    Например:

    ALTER TABLE player ADD (carry_weight AS (strength * 10 + 150));
    
0 голосов
/ 28 января 2011

Я бы точно не использовал триггер для такого рода вещей.Звучит так, будто вам нужна функция, которая принимает параметр ID_PLAYER и возвращает либо значение, либо запись значений.Примерно так (обратите внимание, что я не уверен, что понимаю формулы, которые вы описываете, поэтому я предполагаю, что немного

...