Отдаю в хорошие руки:

- Этот форум.
- Облако

подробности о передаче в личке или на e-mail: vovka3003@ya.ru

Если новый владелец ресурсов не найдется, то форум отключится
автоматически 23.12.2018:
СпойлерПоказать
Изображение
облако - на месяц позже.

Всем кто присутствовал и принимал участие - спасибо!

DataExpress -> ресурс СУБД Firebird

Трёп, флуд, флейм здесь. Реклама, спам и пропаганда наркотиков НЕ приветствуются.
Аватара пользователя
Yuriy
Сообщения: 119
Зарегистрирован: 11 фев 2018, 13:34
Откуда: Киев

DataExpress -> ресурс СУБД Firebird

Сообщение Yuriy » 06 окт 2018, 16:25

У пользователей DataExpress частенько возникают вопросы по разным подсчетам в разных формах и т.п. Используют выражения, редактор скриптов, но ведь есть еще и Firebird 2.5 с большими возможностями по обработке данных в самой СУБД.
+ освобождается клиентская сторона.

Пример на вскидку из PostgreSQL :
ТриггерПоказать

Код: Выделить всё

-- Trigger: t_orders_for_r_courier_payment

-- DROP TRIGGER t_orders_for_r_courier_payment ON public.a_orders;

CREATE TRIGGER t_orders_for_r_courier_payment
    AFTER INSERT OR DELETE OR UPDATE 
    ON public.a_orders
    FOR EACH ROW
    EXECUTE PROCEDURE public.f_add_to_r_courier_payment();

COMMENT ON TRIGGER t_orders_for_r_courier_payment ON public.a_orders
    IS 'триггер заполнения оплаты курьерам';
    
ФункцияПоказать

Код: Выделить всё

-- FUNCTION: public.f_add_to_r_courier_payment()

-- DROP FUNCTION public.f_add_to_r_courier_payment();

CREATE FUNCTION public.f_add_to_r_courier_payment()
    RETURNS trigger
    LANGUAGE 'plpgsql'
    COST 100
    VOLATILE NOT LEAKPROOF 
AS $BODY$
DECLARE

	var_id_orders				integer; -- id заказа
	
    var_date_payment     		date;    -- Новый заказ
    var_id_courier       		integer; -- Новый заказ
    var_id_affiliate     		integer; -- Новый заказ
	var_payment          		integer; -- Новый заказ
	
	id_courier_payment_old      integer; -- Ранее присвоенные данные
    /*id_affiliate_old     		integer; -- Ранее присвоенные данные */
	payment_old          		integer; -- Ранее присвоенные данные
	
	var_id_orders_old			integer; -- Данные заказа до редактирования и удаления
	var_date_payment_old       	date;    -- Данные заказа до редактирования и удаления
	var_id_courier_payment_old 	integer; -- Данные заказа до редактирования и удаления
	var_id_courier_old 			integer; -- Данные заказа до редактирования и удаления
	var_id_affiliate_old 		integer; -- Данные заказа до редактирования и удаления
	var_payment_old      		integer; -- Данные заказа до редактирования и удаления
	
	var_id_summa_hour 		    integer; -- Данные таблицы почасовки
	var_summa_hour      		integer; -- Данные таблицы почасовки
	var_summa_hour_new		    integer; -- Данные таблицы почасовки
	
	count_payment        		integer; -- Проверка существования записи
	count_hour          		integer; -- Проверка существования записи
	count_goods          		integer; -- Проверка существования записи
	var_payment_sum      		integer; -- Результат вычислений
	var_payment_excess    		integer := 0; -- Излишек свыше 1000 грн
	
	
	castr varchar(50);
	astr integer;
	
BEGIN

-- ЗАПИСЬ
	IF TG_OP = 'INSERT' THEN -- новый заказ
	
		var_id_orders    = NEW.id_orders;
	 	var_date_payment = NEW.date_orders;
        var_id_courier   = NEW.id_courier;
        var_id_affiliate = NEW.affiliate;
				
		-- Курьер САМОВЫВОЗ
		IF (var_id_courier = 7) THEN		
			RETURN NEW; --выходим
		END IF;
	
		-- Проверка наличия строки зарплаты курьера
		SELECT COUNT(*) 
		INTO   count_payment 
		FROM   r_courier_payment
		WHERE  date_payment = var_date_payment
		AND    id_courier = var_id_courier
		AND    id_affiliate = var_id_affiliate;

		-- Получаем СУММУ товаров, по которым начисляется зарплата
		SELECT SUM(price_goods * quantity_goods) 
		INTO   var_payment
		FROM   a_orders_goods
		WHERE  orders_id = var_id_orders
		AND    number_table IN (1, 11);
			
		-- Проверка на Минимальный заказ
		IF (var_payment < 100) THEN		
			var_payment = 100;
		END IF;
	
		-- % зарплаты по филлиалу N и др.
		IF ( var_id_affiliate = 2) THEN		
			var_payment_sum = var_payment * 0.395;
		ELSE
			var_payment_sum = var_payment * 0.2;
		END IF;
		
		-- Обрезание излишка при заказе свыше 1000 грн
		IF (var_id_affiliate = 2 AND var_payment_sum > 395) THEN			
				var_payment_excess = var_payment_sum - 395;
				var_payment_sum = 395;
		ELSIF (var_id_affiliate <> 2 AND var_payment_sum > 200) THEN
				var_payment_excess = var_payment_sum - 200;
				var_payment_sum = 200;
		END IF;
		
		-- Занесение излишка в ПОЧАСОВКУ
		IF (var_payment_excess > 0) THEN		
		
			-- Проверка наличия строки излишка в ПОЧАСОВКЕ
			SELECT COUNT(*) 
			INTO   count_hour 
			FROM   r_courier_summa_hour_payment
			WHERE  date_hour = var_date_payment
			AND    id_affiliate = var_id_affiliate;

				-- Новая запись в ПОЧАСОВКУ
			IF (count_hour = 0) THEN

				INSERT INTO r_courier_summa_hour_payment(date_hour, id_affiliate, summa) 
				VALUES      (var_date_payment, var_id_affiliate, var_payment_excess);	

			-- Сложение с существующей записью ПОЧАСОВКИ
			ELSIF (count_hour > 0) THEN			

				-- Получаем старые значения суммы ПОЧАСОВКИ
				SELECT id_summa_hour, summa
				INTO   var_id_summa_hour, var_summa_hour  
				FROM   r_courier_summa_hour_payment
				WHERE  date_hour = var_date_payment
				AND    id_affiliate = var_id_affiliate;			

				var_summa_hour_new = var_summa_hour + var_payment_excess;

				-- Обновляем старые значения суммы ПОЧАСОВКИ
				UPDATE r_courier_summa_hour_payment 
				SET    summa = var_summa_hour_new
				WHERE  id_summa_hour = var_id_summa_hour;		

			END IF;			
		END IF;		
	
		-- Занесение ЗАРПЛАТЫ курьеров в таблицу
		
		-- Новый заказ +- Новый курьер +- Новый филлиал
		IF (count_payment = 0) THEN

			INSERT INTO r_courier_payment(date_payment, id_courier, id_affiliate, payment, get_payment, remain) 
			values      (var_date_payment, var_id_courier, var_id_affiliate, var_payment_sum, '0', '0');
			RETURN NEW;	
			
		-- Новый заказ Существующий курьер Существующий филлиал
		ELSIF (count_payment > 0) THEN

			-- Получаем старые значения ЗАРПЛАТЫ курьера и филлиала нового заказа
			SELECT id_courier_payment, payment 
			INTO   id_courier_payment_old, payment_old  
			FROM   r_courier_payment
			WHERE  date_payment = var_date_payment
			AND    id_courier = var_id_courier
			AND    id_affiliate = var_id_affiliate;			

			--	Подсчет суммы ЗАРПЛАТЫ
			var_payment_sum = var_payment_sum + payment_old;

			-- Обновляем старые значения суммы ЗАРПЛАТЫ
			UPDATE r_courier_payment 
			SET    payment = var_payment_sum
			WHERE  id_courier_payment = id_courier_payment_old;		
		
			RETURN NEW;
			
		END IF;
		
		RETURN NEW;
		
-- РЕДАКТИРОВАНИЕ	
	ELSIF TG_OP = 'UPDATE' THEN -- редактирование заказа
	
		var_id_orders_old    = OLD.id_orders;
		var_date_payment_old = OLD.date_orders;
		var_id_courier_old   = OLD.id_courier;
		var_id_affiliate_old = OLD.affiliate;
		
		var_id_orders    = NEW.id_orders;
	 	var_date_payment = NEW.date_orders;
        var_id_courier   = NEW.id_courier;
        var_id_affiliate = NEW.affiliate;
		
	  -- СТАРЫЙ и НОВЫЙ курьер САМОВЫВОЗ
		IF (var_id_courier_old = 7 AND var_id_courier = 7) THEN 
					
			--Удаляем товары заказа из таблицы оперативных данных register_a_orders_goods
			DELETE FROM  register_a_orders_goods
			WHERE        orders_id = var_id_orders_old;
		
			RETURN NEW;
		
	  -- СТАРЫЙ курьер НЕ САМОВЫВОЗ - НОВЫЙ курьер САМОВЫВОЗ
		ELSIF (var_id_courier = 7 AND var_id_courier_old <> 7) THEN 
	
		-- Проверка наличия товаров заказа в таблице a_orders_goods
			SELECT COUNT(*) 
			INTO   count_goods 
			FROM   a_orders_goods
			WHERE  orders_id = var_id_orders_old;
			
			IF (count_goods > 0)  THEN --> goods
			
				-- Получаем СУММУ товаров, по которым начислялась зарплата ДО РЕДАКТИРОВАНИЯ 
				SELECT SUM(price_goods * quantity_goods) 
				INTO   var_payment_old
				FROM   a_orders_goods
				WHERE  orders_id = var_id_orders_old
				AND    number_table IN (1, 11);			
			
			ELSE -- если товары редактировались
			
				-- Получаем СУММУ товаров, по которым начислялась зарплата ДО РЕДАКТИРОВАНИЯ 
				-- (промежуточная таблица register_a_orders_goods + тригер t_register_a_orders_goods под a_orders_goods)
				SELECT SUM(price_goods * quantity_goods) 
				INTO   var_payment_old
				FROM   register_a_orders_goods
				WHERE  orders_id = var_id_orders_old
				AND    number_table IN (1, 11);

				--Удаляем товары заказа из таблицы оперативных данных register_a_orders_goods
				DELETE FROM  register_a_orders_goods
				WHERE        orders_id = var_id_orders_old;
			
			END IF; -- <- goods

			-- Проверка на Минимальный заказ
			IF (var_payment_old < 100) THEN		
				var_payment_old = 100;
			END IF;

			-- % зарплаты по филлиалу Киев и др.
			IF ( var_id_affiliate_old = 2) THEN		
				var_payment_sum = var_payment_old * 0.395;
			ELSE
				var_payment_sum = var_payment_old * 0.2;
			END IF;

			-- Обрезание излишка при заказе свыше 1000 грн
			IF (var_id_affiliate_old = 2 AND var_payment_sum > 395) THEN			
					var_payment_excess = var_payment_sum - 395;
					var_payment_sum = 395;
			ELSIF (var_id_affiliate_old <> 2 AND var_payment_sum > 200) THEN
					var_payment_excess = var_payment_sum - 200;
					var_payment_sum = 200;
			END IF;

			-- Вычитание излишка из ПОЧАСОВКИ
			IF (var_payment_excess > 0) THEN						

				-- Получаем старые значения суммы ПОЧАСОВКИ
				SELECT id_summa_hour, summa
				INTO   var_id_summa_hour, var_summa_hour  
				FROM   r_courier_summa_hour_payment
				WHERE  date_hour = var_date_payment_old
				AND    id_affiliate = var_id_affiliate_old;			

				--	Подсчет остатка ПОЧАСОВКИ
				var_summa_hour_new = var_summa_hour - var_payment_excess;

				IF (var_summa_hour_new <= 0) THEN -- если один заказ или ошибка, удаляем запись

					-- Удаляем старую строку суммы ПОЧАСОВКИ
					DELETE FROM r_courier_summa_hour_payment
					WHERE       id_summa_hour = var_id_summa_hour;

				ELSE

					-- Обновляем старые значения суммы ПОЧАСОВКИ
					UPDATE r_courier_summa_hour_payment 
					SET    summa = var_summa_hour_new
					WHERE  id_summa_hour = var_id_summa_hour;

				END IF;		
			END IF;		

			-- Получаем старые значения ЗАРПЛАТЫ курьера и филлиала  заказа
			SELECT id_courier_payment, payment 
			INTO   id_courier_payment_old, payment_old  
			FROM   r_courier_payment
			WHERE  date_payment = var_date_payment_old
			AND    id_courier = var_id_courier_old
			AND    id_affiliate = var_id_affiliate_old;

			--	Подсчет остатка ЗАРПЛАТЫ
			var_payment_sum = payment_old - var_payment_sum;

			-- если остатка нет или ошибка, удаляем запись 
			IF (var_payment_sum <= 0) THEN 

				DELETE FROM r_courier_payment
				WHERE       id_courier_payment = id_courier_payment_old;

				RETURN NEW;

			-- если остаток есть, редактируем запись
			ELSE

				UPDATE r_courier_payment 
				SET    payment = var_payment_sum
				WHERE  id_courier_payment = id_courier_payment_old;

				RETURN NEW;

			END IF;			
		END IF;	----<--САМОВЫВОЗ
		
		
	
		-- Получаем СУММУ товаров, по которым начислялась зарплата, ДО РЕДАКТИРОВАНИЯ 
			-- (промежуточная таблица register_a_orders_goods + тригер t_register_a_orders_goods под a_orders_goods)
			SELECT SUM(price_goods * quantity_goods) 
			INTO   var_payment_old
			FROM   register_a_orders_goods
			WHERE  orders_id = var_id_orders_old
			AND    number_table IN (1, 11);

			--Удаляем товары заказа из таблицы оперативных данных register_a_orders_goods
			DELETE FROM  register_a_orders_goods
			WHERE        orders_id = var_id_orders_old;

		-- Получаем СУММУ товаров заказа,  по которым будет начисляться зарплата ПОСЛЕ РЕДАКТИРОВАНИЯ 
			SELECT SUM(price_goods * quantity_goods) 
			INTO   var_payment
			FROM   a_orders_goods
			WHERE  orders_id = var_id_orders
			AND    number_table IN (1, 11);	

		-- При редакции косвенных данных ВЫХОДИМ из функции без изменений	
			IF (var_payment_old = var_payment AND var_date_payment_old = var_date_payment 
				AND var_id_courier_old = var_id_courier AND var_id_affiliate_old = var_id_affiliate) THEN

				RETURN NEW;

			END IF; ---  ВЫХОДИМ из функции без изменений

		-- Удаляем старую запись зарплаты курьера (и вычитаем-удаляем из почасовки излишек, если он был)	

		-- При редакции Суммы (товаров) заказа  ----	
			IF  (var_payment_old <> var_payment)  THEN

		-- При редакции Курьера в заказе
			ELSIF (var_payment_old = var_payment)	THEN

		-- При редакции Филлиала в заказе
			ELSIF (var_payment_old = var_payment)	THEN

		-- При редакции Даты в заказе
			ELSIF (var_payment_old = var_payment) THEN		

			END IF;

			RETURN NEW;
		
-- УДАЛЕНИЕ	
	ELSIF TG_OP = 'DELETE' THEN -- удаление заказа
		
		var_id_orders_old    = OLD.id_orders;
		var_date_payment_old = OLD.date_orders;
		var_id_courier_old   = OLD.id_courier;
		var_id_affiliate_old = OLD.affiliate;
	
		-- Курьер САМОВЫВОЗ
		IF (var_id_courier_old = 7) THEN
		
			--Удаляем товары заказа САМОВЫВОЗ из таблицы товаров
			DELETE FROM  a_orders_goods
			WHERE        orders_id = var_id_orders_old;
			
			--Удаляем товары заказа САМОВЫВОЗ из таблицы временный регистр_товаров
			DELETE FROM  register_a_orders_goods
			WHERE        orders_id = var_id_orders_old;			
			
			RETURN OLD;
		END IF;	------САМОВЫВОЗ			
			
		/*insert into proba(proba_in) 
		values (var_payment_excess);*/		

		-- Получаем СУММУ товаров, по которым начислялась зарплата
		SELECT SUM(price_goods * quantity_goods) 
		INTO   var_payment
		FROM   a_orders_goods
		WHERE  orders_id = var_id_orders_old
		AND    number_table IN (1, 11);
			
		-- Проверка на Минимальный заказ
		IF (var_payment < 100) THEN		
			var_payment = 100;
		END IF;
	
		-- % зарплаты по филлиалу Киев и др.
		IF ( var_id_affiliate_old = 2) THEN		
			var_payment_sum = var_payment * 0.395;
		ELSE
			var_payment_sum = var_payment * 0.2;
		END IF;
		
		-- Обрезание излишка при заказе свыше 1000 грн
		IF (var_id_affiliate_old = 2 AND var_payment_sum > 395) THEN			
				var_payment_excess = var_payment_sum - 395;
				var_payment_sum = 395;
		ELSIF (var_id_affiliate_old <> 2 AND var_payment_sum > 200) THEN
				var_payment_excess = var_payment_sum - 200;
				var_payment_sum = 200;
		END IF;
		
		-- Вычитание излишка из ПОЧАСОВКИ
		IF (var_payment_excess > 0) THEN						

			-- Получаем старые значения суммы ПОЧАСОВКИ
			SELECT id_summa_hour, summa
			INTO   var_id_summa_hour, var_summa_hour  
			FROM   r_courier_summa_hour_payment
			WHERE  date_hour = var_date_payment_old
			AND    id_affiliate = var_id_affiliate_old;			

			--	Подсчет остатка ПОЧАСОВКИ
			var_summa_hour_new = var_summa_hour - var_payment_excess;
					
			IF (var_summa_hour_new <= 0) THEN -- если один заказ или ошибка, удаляем запись

				-- Удаляем старую строку суммы ПОЧАСОВКИ
				DELETE FROM r_courier_summa_hour_payment
				WHERE       id_summa_hour = var_id_summa_hour;

			ELSE
						
				-- Обновляем старые значения суммы ПОЧАСОВКИ
				UPDATE r_courier_summa_hour_payment 
				SET    summa = var_summa_hour_new
				WHERE  id_summa_hour = var_id_summa_hour;

			END IF;		
		END IF;		
				
		-- Получаем старые значения ЗАРПЛАТЫ курьера и филлиала  заказа
		SELECT id_courier_payment, payment 
		INTO   id_courier_payment_old, payment_old  
		FROM   r_courier_payment
		WHERE  date_payment = var_date_payment_old
		AND    id_courier = var_id_courier_old
		AND    id_affiliate = var_id_affiliate_old;
		
		--	Подсчет остатка ЗАРПЛАТЫ
		var_payment_sum = payment_old - var_payment_sum;
		
		-- Удаляем товары заказа из таблицы товаров
		DELETE FROM  a_orders_goods
		WHERE        orders_id = var_id_orders_old;
		
		--Удаляем товары заказа из таблицы оперативных данных register_a_orders_goods
		DELETE FROM  register_a_orders_goods
		WHERE        orders_id = var_id_orders_old;
		
		-- если остатка нет или ошибка, удаляем запись 
		IF (var_payment_sum <= 0) THEN 
		
			DELETE FROM r_courier_payment
			WHERE       id_courier_payment = id_courier_payment_old;

			RETURN OLD;

		-- если остаток есть, редактируем запись
		ELSE

			UPDATE r_courier_payment 
			SET    payment = var_payment_sum
			WHERE  id_courier_payment = id_courier_payment_old;
				
			RETURN OLD;

		END IF;		
	END IF; 
END;

			
		

$BODY$;

ALTER FUNCTION public.f_add_to_r_courier_payment()
    OWNER TO postgres;

COMMENT ON FUNCTION public.f_add_to_r_courier_payment()
    IS 'функция заполнения оплаты курьерам';	

Быстрый ответ

Смайлики
:-) ;-) :-( :-[ :-D :-P O_O :bye: :good: :help: :lol: :ok: :pardon: :sorry: :yes:
Ещё смайлики…
Загрузить изображение