Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как реализовать в процедуре firebird? 
:(
    Опции темы
azcrc
Дата 21.5.2010, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 25.3.2010

Репутация: 1
Всего: 1



Здравствуйте.

Подскажиет пожалуйста пути решения вопроса.

Нужно увеличить KOLVO таблицы STORAGE_RESTS на величину KOLVO таблицы  LINE_DOC для определенных LINE_ID.
По умолчанию STORAGE_RESTS может быть заполнена полностью, частично, или пустая.
Суть: товар приходит на склад по документу.

Я срез схемы нарисовал, чтобы легче было для восприятия.
PRODUCT_ID - первичный ключ, автоинкр. (тригер, ген)

Схема тут: http://xmages.net/upload/eeadd0cd.png

Какими этапами это правильно делается?

---
Первый шаг, это понимаю, select * from LINE_DOC where LINE_ID > tratata.
Это выберет исходную таблицу.
А как правильно сделать апдейт (и местами инсерт) в STORAGE_RESTS?

Это сообщение отредактировал(а) azcrc - 21.5.2010, 15:04
PM MAIL   Вверх
Gluttton
Дата 21.5.2010, 14:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



Код

update storage_rests
    values(kolvo)
set 
    storage_rests.kolvo = storage_rests.kolvo + 
    (
        select sum(line_doc.kolvo) as sum_kolvo
        from 
            line_doc, 
            products, 
            storage_rests as alias_storage_rests
        where line_doc.products = products.product_id
        and products.product_id = alias_storage_rests.products
        and alias_storage_rest.products = storage_rest.products
        where line_id in
        (
            -- здесь перчень line_id из которых необходимо добавлять данные
        )
    )


Давненько я уже запросы не писал smile ...
Писал "из головы" скорее всего будут ошибки...
Оно?


--------------------
Слава Україні!
PM MAIL   Вверх
azcrc
Дата 21.5.2010, 14:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 25.3.2010

Репутация: 1
Всего: 1



Нет, не оно.
И дело даже не в сумме.
Нужно просто плюсануть количество STORAGE_RESTS количеством LINE_DOC для каждой записи по PRODUCT_ID.
Как-то так ( набросок smile ) это ход моей мысли:
Код

UPDATE storage_rests SET storage_rests.kolvo = kolvo+line_doc.kolvo
WHERE storage_rests.products = line_doc.products
ДЛЯ ВСЕХ ИЗ line_doc ГДЕ  line_doc.line_id = 123

При условии, что в storage_rests может быть изначально пусто. Т.е. надо где апдейт, а где и инсерт. Процедурой...

Суть: В line_doc есть записи, вот уже пуcть они будут выделены: 
Код

select * from LINE_DOC

их количества (LINE_DOC.kolvo) надо оттащить в storage_rests (апдейт/инсерт).

Это сообщение отредактировал(а) azcrc - 21.5.2010, 15:36
PM MAIL   Вверх
Gluttton
Дата 21.5.2010, 15:00 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



А обязательно одним запросом?

Если нет, то сначала можно определить те записи, которых нет в storage_rests и есть в doc_line, добавить их в storage_rests с количеством "0", затем применить update...


--------------------
Слава Україні!
PM MAIL   Вверх
azcrc
Дата 21.5.2010, 15:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 25.3.2010

Репутация: 1
Всего: 1



Обязательно в рамках одной быстрой процедуры.
Была мысль, сделать сначала вставку с нулями, а потом апдейт.
Но во-первых, я не знаю как и сейчас ищу информацию/примеры (где-то видел на днях), и если найду, то это может быть не быстрый способ. А может и приемлимый.

И извиняюсь, line_id - это просто поле, не уникальное и не счетчик.

Это сообщение отредактировал(а) azcrc - 21.5.2010, 15:09
PM MAIL   Вверх
Gluttton
Дата 21.5.2010, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



Цитата(azcrc @  21.5.2010,  15:09 Найти цитируемый пост)
Но во-первых, я не знаю как

Что конкретно не понятно?

Как показывает практика, дело пойдет гораздо быстрее, если будут предоставлен тестовый набор данных с пояснением, что необходимо получить (можно выложить БД или ее кусочек если она большая smile )...


--------------------
Слава Україні!
PM MAIL   Вверх
azcrc
Дата 21.5.2010, 16:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 25.3.2010

Репутация: 1
Всего: 1



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

Нарисовал картинку вот, если чем поможет:
http://xmages.net/upload/96a73b38.png


UPD
Весь день проковырялся, и не подумал бы куда копать, а вот, оказывается, как правильно:
http://www.firebirdsql.org/rlsnotesh/rlsno...l#rnfb210-merge

Это сообщение отредактировал(а) azcrc - 21.5.2010, 17:19
PM MAIL   Вверх
Gluttton
Дата 21.5.2010, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



Цитата(azcrc @  21.5.2010,  16:48 Найти цитируемый пост)
Весь день проковырялся, и не подумал бы куда копать, а вот, оказывается, как правильно:http://www.firebirdsql.org/rlsnotesh/rlsno...l#rnfb210-merge

Почитаем...

А у меня вот что получилось:
Код

/*============================================================*/
/*=== Create DataBase FOOD.FDB                             ===*/
/*============================================================*/

SET AUTODDL ON;

CONNECT DATABASE 'FOOD' USER 'SYSDBA' PASSWORD 'masterkey';
DROP DATABASE;

SET SQL DIALECT 3;
SET NAMES WIN1251;
CREATE DATABASE 'FOOD' USER 'SYSDBA'
PASSWORD 'masterkey' PAGE_SIZE 16384 DEFAULT CHARACTER SET WIN1251;

/*============================================================*/ 
/*=== Create Domains                                       ===*/
/*============================================================*/

CREATE DOMAIN ID       AS BIGINT                      NOT NULL;
CREATE DOMAIN NAME     AS VARCHAR(10)                 NOT NULL;
CREATE DOMAIN QUANTITY AS INTEGER      DEFAULT 0      NOT NULL;

/*============================================================*/
/*=== Create Generators                                    ===*/
/*============================================================*/

CREATE GENERATOR Products;

/*============================================================*/
/*=== Create Tables                                        ===*/
/*============================================================*/

CREATE TABLE Products
(
    ID       ID,
    NAME     NAME
);

CREATE TABLE Documents
(
    PRODUCT  ID,
    QUANTITY QUANTITY
);

CREATE TABLE Storage
(
    PRODUCT  ID,
    QUANTITY QUANTITY
);

/*============================================================*/
/*=== Declaration primary keys                             ===*/
/*============================================================*/

ALTER TABLE Products ADD CONSTRAINT
    PK_Products PRIMARY KEY(ID);
ALTER TABLE Storage  ADD CONSTRAINT
    PK_Storage  PRIMARY KEY(PRODUCT);

/*============================================================*/
/*=== Declaration foreigns keys                            ===*/
/*============================================================*/

ALTER TABLE Documents ADD CONSTRAINT FK_Documents_Products
    FOREIGN KEY(PRODUCT) REFERENCES Products(ID);
ALTER TABLE Storage ADD CONSTRAINT FK_Storage_Products
    FOREIGN KEY(PRODUCT) REFERENCES Products(ID);

/*============================================================*/
/*=== Create Triggers                                      ===*/
/*============================================================*/

/*------------------------------------------------------------*/
/*--- Create Trigger (Insert ID into Products)             ---*/
/*------------------------------------------------------------*/

SET TERM ^;

CREATE TRIGGER Products_ID
FOR Products ACTIVE BEFORE INSERT
POSITION 0 AS
BEGIN
    IF (NEW.ID IS NULL)
    THEN NEW.ID=GEN_ID (Products, 1);
END^

SET TERM ;^

COMMIT;

/*============================================================*/
/*=== Create Procedures                                    ===*/
/*============================================================*/

/*------------------------------------------------------------*/
/*--- Create Procedure (Insert data from Documents into    ---*/
/*--- Products)                                            ---*/
/*------------------------------------------------------------*/

SET TERM ^;

RECREATE PROCEDURE UDP
AS
BEGIN
    /* --- First step --- */
    INSERT INTO Storage
        SELECT DISTINCT
            Documents.Product,
            0
        FROM Documents
            LEFT JOIN Storage
            ON Documents.Product = Storage.Product
                WHERE Storage.Product IS NULL;
    /* --- Second step --- */
    UPDATE Storage
    SET Storage.QUANTITY = Storage.QUANTITY +
    (
        SELECT
            SUM(Documents.QUANTITY) as Q
        FROM Documents, Storage as S
            WHERE S.PRODUCT = Documents.PRODUCT
            AND S.PRODUCT = Storage.PRODUCT
    );
END ^

SET TERM ;

COMMIT;

/*============================================================*/
/*=== Insert data in table Products                        ===*/
/*============================================================*/

INSERT INTO Products(ID, NAME) VALUES (1, 'Vine');
INSERT INTO Products(ID, NAME) VALUES (2, 'Fish');
INSERT INTO Products(ID, NAME) VALUES (3, 'Meet');
INSERT INTO Products(ID, NAME) VALUES (4, 'Beer');
INSERT INTO Products(ID, NAME) VALUES (5, 'Milk');

/*============================================================*/
/*=== Insert data in table Documents                       ===*/
/*============================================================*/

INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (1, 500);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (1, 1500);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (2, 10);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (3, 45);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (4, 5);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (4, 5);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (5, 1000);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (5, 1000);
INSERT INTO Documents(PRODUCT, QUANTITY) VALUES (5, 750);

/*============================================================*/
/*=== Insert data in table Storage                         ===*/
/*============================================================*/

INSERT INTO Storage(PRODUCT, QUANTITY) VALUES (1, 100);
INSERT INTO Storage(PRODUCT, QUANTITY) VALUES (2, 50);
INSERT INTO Storage(PRODUCT) VALUES (3);

COMMIT; 


Код

select * from Storage

PRODUCT  QUANTITY
      1       100  
      2        50  
      3         0  


select * from Documents

PRODUCT  QUANTITY
      1       500  
      1     1 500  
      2        10  
      3        45  
      4         5  
      4         5  
      5     1 000  
      5     1 000  
      5       750  


execute procedure UDP;


select * from Storage

PRODUCT  QUANTITY
      1     2 100  
      2        60  
      3        45  
      4        10  
      5     2 750  


Это сообщение отредактировал(а) Gluttton - 22.5.2010, 09:39


--------------------
Слава Україні!
PM MAIL   Вверх
azcrc
Дата 22.5.2010, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 25.3.2010

Репутация: 1
Всего: 1



Спасибо, пример тоже довольно интересный smile
PM MAIL   Вверх
Gluttton
Дата 22.5.2010, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Начинающий
***


Профиль
Группа: Завсегдатай
Сообщений: 1170
Регистрация: 28.8.2008
Где: Феодосия

Репутация: 24
Всего: 54



Цитата(azcrc @  22.5.2010,  14:52 Найти цитируемый пост)
Спасибо

Незачто smile ...

Цитата(azcrc @  22.5.2010,  14:52 Найти цитируемый пост)
пример тоже довольно интересный

Важно не то, что он интересный, а то, что он воспроизводимый, и если теперь, кто-нибудь решит подключиться к решению проблемы, то ему не прийдется оперировать данными "в голове" или же создавать свою БД и набивать туда данные с картинки, а достаточно будет воспользоваться готовым скриптом  smile ...


--------------------
Слава Україні!
PM MAIL   Вверх
Zloxa
Дата 23.5.2010, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(azcrc @  21.5.2010,  16:48 Найти цитируемый пост)
merge

ухты, я и не знал что FB так умеет.


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.0710 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.