2011-01-28 2 views
1

У меня есть следующая проблема. В моем приложении пользователь создает игровой символ, используя систему SPECIAL (Сила, Восприятие и т. Д. Со значениями от 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 и radiation_resistance для каждого Игрока. Предположим, что все формулы: (player_parameter * 10) + 150. Что было бы лучше использовать: триггер или процедура?


EDIT

Я пытаюсь использовать код от ответа, но я получаю сообщение об ошибке 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; 

ответ

0

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

CREATE OR REPLACE PACKAGE pkg_player_stats 
AS 
    TYPE derived_stats_rec IS RECORD (
    carry_weight NUMBER, 
    hit_points NUMBER, 
    radiation_resistance NUMBER); 

    FUNCTION get_derived_stats(p_id_player IN player.id_player%TYPE) 
    RETURN derived_stats_rec; 
END; 

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 carry_weight   * multiplier + 150, 
      hit_points   * multiplier + 150, 
      radiation_resistance * multiplier + 150 
     INTO l_stats_rec.carry_weight, 
      l_stats_rec.hit_points, 
      l_stats_rec.radiation_resistance 
     FROM (
     SELECT p.strength + 
       p.perception + 
       p.endurance + 
       p.charisma + 
       p.inteligence + 
       p.agility + 
       p.luck multiplier, 
       s.carry_weight, 
       s.hit_points, 
       s.radiation_resistance 
      from player p 
       inner join player_derived_statistics s on s.id_statistics = p.statistics); 
    RETURN l_stats_rec; 
    END get_derived_stats; 
END; 
0

Почему вам нужно две таблицы? Я бы ни с

  • Одна таблицы только все ОСОБОЙ статистикой и вид, который вычисляет производные статистические данные (в приложении вы запросить мнение):

    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, вы также можете использовать virtual column:

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

    Например:

    ALTER TABLE player ADD (carry_weight AS (strength * 10 + 150)); 
    
+0

У меня уже есть Тхо всей БД создана таким образом, я хотел бы придерживаться этого. –

+0

Наличие хорошей модели поможет вам в долгосрочной перспективе. –

 Смежные вопросы

  • Нет связанных вопросов^_^