Мне нужно добавить автоматический расчет c для атрибута «ВОЗРАСТ», который необходимо вычислить в oracle - PullRequest
0 голосов
/ 01 апреля 2020

enter image description here

enter image description here

если у меня есть «INSERT INTO», мне нужны дополнительные автоматы c вычисление для атрибута «ВОЗРАСТ», который необходимо вычислить Я пробовал

create or replace TRIGGER AGE_CALC03 BEFORE INSERT OR UPDATE ON EMPLOYEES
FOR EACH ROW BEGIN
:new.AGE := SYSDATE - :new.BIRTH_DATE; 
END AGE_CALC03;”

Ответы [ 3 ]

1 голос
/ 01 апреля 2020

Наличие столбца AGE - плохой выбор, поскольку он станет неправильным, если данные в строке не обновляются регулярно.

Однако я подозреваю, что это школьное задание, и вас не волнует проблемы дизайна. Хорошо - причина, по которой ваш триггер не дает вам хорошего значения для AGE, состоит в том, что расчет просто неверен. Вы вычитаете одно свидание из другого, думая, что это даст вам разницу в годах. Это не так - это дает вам разницу в ДНЕЙ .

Правильный расчет для AGE равен FLOOR(MONTHS_BETWEEN(SYSDATE, BIRTH_DATE) / 12). Поэтому ваш триггер должен показывать:

CREATE OR REPLACE TRIGGER AGE_CALC03
  BEFORE INSERT OR UPDATE ON EMPLOYEES
  FOR EACH ROW
BEGIN
  :new.AGE := FLOOR(MONTHS_BETWEEN(SYSDATE, :new.BIRTH_DATE) / 12); 
END AGE_CALC03;

Но - вернемся к проблемам со столбцом AGE. Лучший способ узнать возраст сотрудников - это вызвать функцию, которая возвращает вам возраст людей в зависимости от даты их рождения. Что-то вроде следующего:

FUNCTION COMPUTE_AGE(pinBirth_date IN DATE)
  RETURN NUMBER
AS
BEGIN
  RETURN FLOOR(MONTHS_BETWEEN(SYSDATE, pinBirth_date ) / 12)
END COMPUTE_AGE;

Затем избавьтесь от столбца AGE в таблице EMPLOYEES и вызывайте эту функцию каждый раз, когда вам нужен чей-то возраст, который затем будет правильным в любой данный момент времени.

1 голос
/ 01 апреля 2020

В Oracle 12 и более поздних версиях используйте виртуальный столбец и детерминированную c функцию:

CREATE FUNCTION calculate_age(
  birth_date DATE,
  now_date   DATE DEFAULT SYSDATE
) RETURN INTEGER DETERMINISTIC
IS
BEGIN
  RETURN FLOOR( MONTHS_BETWEEN( now_date, birth_date ) / 12 );
END;
/

и:

CREATE TABLE EMPLOYEES (
  EMPLOYEE_ID           VARCHAR2(5 BYTE)
                        CONSTRAINT EMPLOYEES__EMPLOYEE_ID__NN NOT NULL
                        CONSTRAINT EMPLOYEES__EMPLOYEE_ID__PK PRIMARY KEY,
  FIRST_NAME            VARCHAR2(100 BYTE),
  LAST_NAME             VARCHAR2(100 BYTE),
  IDENTIFICATION_NUMBER NUMBER(13,0),
  MANAGER_ID            VARCHAR2(5 BYTE)
                        CONSTRAINT EMPLOYEES__MANAGER_ID__FK REFERENCES EMPLOYEES ( EMPLOYEE_ID ),
  DEPARTMENT_ID         VARCHAR2(1 BYTE),
  WORKING_STATUS        VARCHAR2(1 BYTE),
  BIRTH_DATE            DATE,
  AGE                   INTEGER
                        GENERATED ALWAYS AS ( calculate_age( BIRTH_DATE ) ) VIRTUAL
);

Затем, если вы вставите некоторые образцы данных :

INSERT INTO EMPLOYEES ( EMPLOYEE_ID, BIRTH_DATE )
SELECT 'Alice', DATE '2000-01-01' FROM DUAL UNION ALL
SELECT 'Bob',   DATE '1990-01-01' FROM DUAL UNION ALL
SELECT 'Carol', DATE '1980-01-01' FROM DUAL;

и запросите возраст:

SELECT Employee_id, birth_date, age FROM employees;

Вы получите вывод:

EMPLOYEE_ID | BIRTH_DATE          | AGE
:---------- | :------------------ | --:
Alice       | 2000-01-01 00:00:00 |  20
Bob         | 1990-01-01 00:00:00 |  30
Carol       | 1980-01-01 00:00:00 |  40

дБ <> скрипка здесь

0 голосов
/ 01 апреля 2020
  1. Если у вас уже есть столбец birth_date в вашей системе, почему у вас также есть столбец Age. Это избыточность данных. Всякий раз, когда вам нужно показать возраст, вы можете просто использовать свои логики c как SYSDATE - BIRTH_DATE.

  2. Если вам строго необходимо использовать столбец AGE в вашей таблице, вы должны использовать TRIGGER как вы в настоящее время используете. У вас есть какие-либо проблемы с этим?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...