Форум программистов, компьютерный форум, киберфорум
Oracle
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 6
1

Использование функции или процедуры и другие интересные вещи

31.05.2016, 01:39. Показов 1017. Ответов 5

Здравствуйте.
Хотелось посоветоваться со знающими людьми относительно некоторой возникшей проблемы и её решения.

Есть таблица менеджеры.
Также есть таблица типы квартир.
Каждому менеджеру может принадлежать не более двух типов квартир, за которые он отвечает. Это тоже отдельная таблица, носит название "Прикрепление".
В этой таблице содержится три поля: порядковый номер (PK)*, id менеджера (FK), тип квартиры (FK).

Теперь вопрос: что лучше создать для подсчета встречаемых менеджеров в записях (напоминаю - их должно быть не более двух), как проконтролировать этот ввод? а также с помощью чего можно реализовать, чтобы не было повторяющихся записей по двум полям одновременно - id менеджера и типа квартиры? (не записывалось, будто у одного менеджера дважды один и тот же тип квартиры).

* - прошу не советовать мне сделать составной первичный ключ. Или, если предложите, хотелось бы узнать, как можно использовать составной ключ в других таблицах. (Само предложение крайне нежелательно, так как придется перестраивать всю базу).

Это сами таблицы:
Менеджеры:
SQL
1
2
3
4
5
6
7
8
CREATE TABLE managers 
(
id_manager NUMBER(10) PRIMARY KEY,
C_LAST_NAME VARCHAR2(100) NOT NULL, 
C_FIRST_NAME VARCHAR2(100) NOT NULL, 
C_SECOND_NAME VARCHAR2(100), 
phone NUMBER(20) NOT NULL UNIQUE
)
Типы квартир:
SQL
1
2
3
CREATE TABLE TYPE_FLAT 
(code NUMBER(10) PRIMARY KEY,
name  VARCHAR2(100) UNIQUE NOT NULL)
Прикрепление:
SQL
1
2
3
4
5
6
CREATE TABLE appointment
(
app_number NUMBER(10)PRIMARY KEY,
ID_man NUMBER REFERENCES managers(id_manager),
type_flat NUMBER REFERENCES type_flat(code)
)
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
31.05.2016, 01:39
Ответы с готовыми решениями:

Запретить использование процедуры или функции в классе-потомке
вообщем описываю новый класс(b) на основе другого класса(a). как можно запретить использование в...

Будет ли корректным вызывать внутри методов get или set другие функции или менять свойства контролов?
Всем привет. Скажите разрешается, не в том смысле, что понятно все разрешено, а будет ли...

Использование подпрограмм. Функции и процедуры
Ниже есть уравнения, как прописать оконное приложение для расчета значений с использованием...

Процедуры, Функции. Организация и Использование
Помогите плиз решить 2 задачки для зачета... 1) Органицазия процедур. Использование процедур. ...

5
759 / 660 / 195
Регистрация: 24.11.2015
Сообщений: 2,160
31.05.2016, 10:44 2
Лучший ответ Сообщение было отмечено Ilesnoy как решение

Решение

Пришлось сделать временную таблицу, чтобы записывать туда данные.
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
CREATE GLOBAL TEMPORARY TABLE tmpd_appointment
   (man_id                         NUMBER,
    type_flat                      NUMBER,
    cnt                            NUMBER)
ON COMMIT DELETE ROWS

Я несколько изменил таблицу APPOINTMENT (добавил еще одно поле), навесил на таблицу уникальный индекс и чек и добавил несколько триггеров: один, чтобы заполнялся первичный ключ, остальные - чтобы менялcя счетчик.
Все работает, все меняется как надо.
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
CREATE TABLE appointment
   (app_number      NUMBER(10)PRIMARY KEY,
    ID_man          NUMBER REFERENCES managers(id_manager),
    type_flat       NUMBER REFERENCES type_flat(code),
    cnt             NUMBER DEFAULT 1 NOT NULL);       -- добавлено поле счетчика
 
CREATE UNIQUE INDEX ui_appointment ON appointment      -- добавлен уникальный индекс
  ( man_id                          ASC,
    type_flat                       ASC
  );
 
--  проверка на <=2 выполняется отложенно при завершении транзакции; если нарушается, транзакция откатывается
ALTER TABLE appointment
ADD CONSTRAINT check_cnt CHECK (cnt <=2)
DEFERRABLE INITIALLY DEFERRED ENABLE NOVALIDATE
;
 
CREATE OR REPLACE TRIGGER APP_BI
 BEFORE 
 INSERT
 ON APPOINTMENT
 REFERENCING OLD AS OLD NEW AS NEW
 FOR EACH ROW
BEGIN
    :NEW.app_id := app_seq.NEXTVAL;  -- присвоение первичного ключа; в другой базе может быть другая последовательность
END;
 
CREATE OR REPLACE TRIGGER APP_BIUD
 BEFORE INSERT OR UPDATE OR DELETE 
 ON APPOINTMENT
BEGIN
    DELETE FROM tmpd_appointment;   -- подготовка временной таблицы
END;
 
CREATE OR REPLACE TRIGGER APP_AIUD1
 AFTER 
 INSERT OR DELETE OR UPDATE
 ON APPOINTMENT
 REFERENCING OLD AS OLD NEW AS NEW
 FOR EACH ROW
BEGIN
    -- заполнение временной таблицы при различных операциях
    IF inserting OR updating THEN
        INSERT INTO tmpd_appointment(man_id, type_flat, cnt)
        VALUES(:NEW.man_id, :NEW.type_flat, NULL);
    END IF;
    IF deleting OR updating THEN
        INSERT INTO tmpd_appointment(man_id, type_flat, cnt)
        VALUES(:OLD.man_id, :OLD.type_flat, NULL);
    END IF;
END;
 
CREATE OR REPLACE TRIGGER APP_AIUD2
 AFTER 
 INSERT OR DELETE OR UPDATE
 ON APPOINTMENT 
DECLARE
    v_cnt     NUMBER;
BEGIN
    FOR vv IN (SELECT DISTINCT man_id FROM tmpd_appointment)  -- проход по временной таблице
    LOOP
        SELECT COUNT(DISTINCT type_flat) INTO v_cnt     -- подсчет числа записей
        FROM appointment
        WHERE man_id=vv.man_id;
        UPDATE appointment           -- изменение счетчиков, если надо менять
           SET cnt = v_cnt 
        WHERE man_id=vv.man_id AND cnt<>v_cnt;
    END LOOP;
END;

Не исключаю, что у меня все слишком сложно, и можно проще. Но работает

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

Добавлено через 2 минуты
Кстати, а причем здесь функция и процедура из названия темы? И где они?
1
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 6
31.05.2016, 11:00  [ТС] 3
Я предполагала писать для проверки правильности вводимых значений процедуру или функцию, но не знала, что лучше подойдет для цели. Поэтому в теме и написано "процедура или функция".
0
759 / 660 / 195
Регистрация: 24.11.2015
Сообщений: 2,160
31.05.2016, 11:21 4
Цитата Сообщение от Ilesnoy Посмотреть сообщение
прошу не советовать мне сделать составной первичный ключ
Я никогда не понимал, почему в Oracle люди рвутся делать специальные первичные ключи, если комбинация каких-то полей уникальна и вполне может работать как первичный ключ. В некоторых Microsoft-приложениях, да, понятно. Там есть (были) ограничения на вид первичного ключа (А может теперь и в Microsoft нет этой дури, давно не работал). Но в Oracle зачем?

Добавлено через 5 минут
Цитата Сообщение от Ilesnoy Посмотреть сообщение
придется перестраивать всю базу
А кто мешает сделать составной первичный ключ только в одной таблице - там где это удобно? И не перестраивать базу?
0
0 / 0 / 0
Регистрация: 04.06.2015
Сообщений: 6
31.05.2016, 11:35  [ТС] 5
Цитата Сообщение от AGK Посмотреть сообщение
Я никогда не понимал, почему в Oracle люди рвутся делать специальные первичные ключи, если комбинация каких-то полей уникальна и вполне может работать как первичный ключ. В некоторых Microsoft-приложениях, да, понятно. Там есть (были) ограничения на вид первичного ключа (А может теперь и в Microsoft нет этой дури, давно не работал). Но в Oracle зачем?
Пожалуй, Вы правы, было бы лаконичнее использовать составной ключ. Но я могу Вам ответить, почему люди рвутся так делать на примере себя: от незнания. Работа с первичным ключом мне казалась проще, чем с составным, поэтому я выбрала этот вариант. Возможно, у других людей причины сходны.

Цитата Сообщение от AGK Посмотреть сообщение
А кто мешает сделать составной первичный ключ только в одной таблице - там где это удобно? И не перестраивать базу?
Дело в том, что я не знаю, как это реализовать.
0
759 / 660 / 195
Регистрация: 24.11.2015
Сообщений: 2,160
31.05.2016, 11:55 6
Лучший ответ Сообщение было отмечено Ilesnoy как решение

Решение

Цитата Сообщение от Ilesnoy Посмотреть сообщение
я не знаю, как это реализовать.
Например, для таблицы APPOINTMENT это можно прямо сейчас реализовать так:
Кликните здесь для просмотра всего текста
SQL
1
2
3
4
5
6
ALTER TABLE appointment
DROP PRIMARY KEY;
 
ALTER TABLE appointment
ADD PRIMARY KEY(man_id, type_flat)
USING INDEX  ui_appointment;

И тогда триггер APP_BI можно удалять. Равно как и поле APP_ID
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
31.05.2016, 11:55

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

Нахождение числа Рейнольдса. Использование функции и процедуры
Как будет выглядеть программа, если в ней предусмотреть и функцию и процедуру? {$APPTYPE CONSOLE}...

Что такое процедуры и функции в паскале, их построение и использование?
Процедуры и функции в паскале, а точнее построение и использование что это? в инете ничего толком...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru