1 Востаннє редагувалося fed_lviv (10.11.2015 11:53:31)

Тема: MySQL вихід з тригера (SQLite raise)

Є таблиця СКЛАД:

CREATE TABLE `storehouse` (
  `idTool` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `nameTool` varchar(100) NOT NULL,
  `countTool` int(3) unsigned NOT NULL DEFAULT '0',
  PRIMARY KEY (`idTool`),
  UNIQUE KEY `nameTool_UNIQUE` (`nameTool`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

Є таблиця ВИДАНИХ ІНСТРУМЕНТІВ

CREATE TABLE `staffTools` (
  `idStaffTools` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `boardNumber` char(4) NOT NULL,
  `idTool` int(10) unsigned NOT NULL,
  `stratDate` date DEFAULT NULL,
  `endDate` date DEFAULT NULL,
  PRIMARY KEY (`idStaffTools`),
  KEY `boardNumberFK` (`boardNumber`),
  KEY `idToolFK` (`idTool`),
  CONSTRAINT `idToolFK` FOREIGN KEY (`idTool`) REFERENCES `storehouse` (`idTool`) ON UPDATE CASCADE,
  CONSTRAINT `boardNumberFK` FOREIGN KEY (`boardNumber`) REFERENCES `staff` (`boardNumber`) ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

Коли ВИДАЄТЬСЯ ІНСТРУМЕНТ ПРАЦІВНИКУ, тобто додається запис в таблицю ВИДАНІ ІНСТРУМЕНТИ, вішаю на таблицю тригери. BEFORE щоб тригер перевіряв чи є даний товар на складі AFTER щоб тригер відмінусовував товар на складі.
І ось з перевіркою товару виникає проблема, якщо товару не має на складі, як вийти з тригера не додавши в таблицю ВИДАНИХ ІНСТРУМЕНТІВ запис? Наприклад в SQLite, можна легко вирішити дану задачу, скориставшись RAISE(ABORT, "Не має даного товару"). Читав про SIGNAL, але в мене MySQL 5.4. Все, що знайшов, це створення помилки в тригері власноруч:

DELIMITER $$

CREATE TRIGGER beforeAddTool BEFORE INSERT ON staffTool FOR EACH ROW
    BEGIN
        IF (SELECT countTool FROM storehouse WHERE idTool = NEW.idTool) < 1 THEN
            UPDATE `Даного товару не має на складі` SET x=1;
    END IF;
    END$$

DELIMITER ; 

Але, щось мені такий варіант не дуже подобається. Підкажіть будь-ласка, як краще вирішити дану задачу?

Подякували: coder1

2 Востаннє редагувалося Itari (10.11.2015 13:16:40)

Re: MySQL вихід з тригера (SQLite raise)

щоб тригер відмінусовував товар на складі.

Це самий гірший варіант, який тільки можна примінити у ведені товарів.
Одумайся, поки біда не сталась.
Ні в якому разі не корегуй залишкі складові таким варварським методом - бо це робиться за допомогою накладної чибто прибутково вибуткового ордеру. Завдяки таким ордерам кількість товару підтримуеться актуально завжди, и залишки коректно можно порахувати за будьякий період.

Подякували: koala1

3

Re: MySQL вихід з тригера (SQLite raise)

Itari дякую, за пораду, ніколи зі складом не працював, тому, про всілякі накладні (ордери) чув тільки краєм вуха. На майбутнє буду знати.
Але це не змінює, моєї задачі. Дана БД не є РЕАЛЬНИМ СКЛАДОМ. Ніяких накладних не має і не буде, нажаль. Просто буде раз в рік поступати пару інструментів(товарів) (викрутка, дрель, чоботи) і буде роздаватись людям. Ніхто не хоче вести паперову волокіту, тому хочуть зробити, гм? ЕЛЕКТРОННИЙ ВАРІАНТ ОСОБОВОЇ КАРТКИ ПО ІНСТРУМЕНТАХ, що в кого є. Таблиця склад, буде умовним складом, щоб дивитися, що ще не роздано.

4 Востаннє редагувалося Itari (10.11.2015 13:46:57)

Re: MySQL вихід з тригера (SQLite raise)

це не змінює, моєї задачі.

Ще як змінює. Замість ненадійних триггеров ти робиш одну ХП, яка буде робити запис з полями:
1) Номенклатура чи інвентарка товару (приладу)
2) Код звідкіля товар надходить
3) Код, куди товар передають
4) Дата та час передачи

Все. Більш ничого не треба для фіксації руху товарів чиб то матцінностей.
Отака запісь і є той самой єлектронной накладной. Ніякого паперового варіанту не буде, якщо так і зробиш.
А щоб дивитися де що кому роздано - формуеться обігово-сальдова відомість та картка руху товарів - де указано коли та куди передавався товар.
І я тебе разочарую: Твоя БД як раз і є тим самим складом, бо матеріальні цінності і в Африці саме таки. Тому моя тобі порада - поки не піздно, одумайся та перероби стратегію своеї БД.

5

Re: MySQL вихід з тригера (SQLite raise)

Для того, щоб зв'язано виконувати дві дії, існують транзакції.
Тригери потрібні, що для будь-якої події в базі щось виконувати, наприклад, вести лог - тобто якщо у вас є купа місць, звідки надходять різноманітні запити, і ви боїтеся, що хтось забуде записати лог. А тут - однозначно транзакція.

6

Re: MySQL вихід з тригера (SQLite raise)

А тут - однозначно транзакція.

Не просто транзакція. Найголовніше - недопустити корегування залишків навпростець, тобто змінювати цифри прямо у таблицях. Бо така каша-малаща потім буде - жодна інвентарізация не зійдеться.
Я це добре знаю, бо не перший рік з документообігом працюю. Надивився вже такі "корегування" поточних показників... Найстрашніщі хоррори МВЛ, не іначе.

Подякували: koala1

7

Re: MySQL вихід з тригера (SQLite raise)

Дякую за поради. Трішки подумаю (почухаю потилицю) і щось буду робити.

8 Востаннє редагувалося fed_lviv (10.11.2015 16:33:36)

Re: MySQL вихід з тригера (SQLite raise)

Itari написав:

2) Код звідкіля товар надходить
3) Код, куди товар передають

Трішки заплутався, чи правильно тебе зрозумів, ти пропонуєш, ось так:
http://s018.radikal.ru/i502/1511/0c/5ad9234ff190t.jpg

9

Re: MySQL вихід з тригера (SQLite raise)

ти пропонуєш, ось так

Так. Щось таке...
1) ID працівника
2) ID Складу (чи МВО)
3) Код операції (Вибуття від МВО, прибуття до працівника, списання, тощо...)
4) Дата проводки.

При цьому найгарніше (чому я про ХП мовлю) треба робити два записи: Перший - списання від МВО, другий - Передача працівнику. Такі пари списання-передачі саме ї формують рух матзабеспечення.

Подякували: fed_lviv1