Форум: "Базы";
Текущий архив: 2005.03.20;
Скачать: [xml.tar.bz2];
Вниз
Странно необъяснимое поведение хранимой процедуры в Фаерберде ... Найти похожие ветки
← →
Rule © (2005-02-17 12:23) [0]При выполнении хранимой процедуры выдает неправильные результаты, а в режиме отладки выдает правильные результаты, до этого встречался с такой проблеммой ... и решил её путем преставления срок кода, причем это переставление логики никакой не меняло вообще ... опять столкнулся с такойже проблеммой ... что делать, чего посоветуете ?
← →
Rule © (2005-02-17 12:26) [1]тело процедуры для полной информации
CREATE PROCEDURE SHOWPRICEFUEL (
NPRICE INTEGER)
RETURNS (
IDFUEL INTEGER,
NAME VARCHAR(20),
PRICE NUMERIC(15,2),
ADATIME TIMESTAMP)
AS
DECLARE VARIABLE DISCOUNTTYPE SMALLINT;
DECLARE VARIABLE PRICE0 NUMERIC(15,2);
begin
for select id, name from fuel
into :idfuel, :name
do
begin
/*забираем стеллогвскую цену и дату активации*/
select a.price, a.adatime, a.discounttype
from pricefuel a
where a.id_fuel=:idfuel
and a.nprice=:nprice
and a.adatime=(select max(b.adatime) from pricefuel b
where b.id_fuel=:idfuel and b.nprice=:nprice)
into :PRICE, :adatime, :DISCOUNTTYPE;
if (Discounttype!=0) then
begin
select a.price
from pricefuel a
where a.id_fuel=:idfuel
and a.nprice=0
and a.adatime=(select max(b.adatime) from pricefuel b
where b.id_fuel=:idfuel and b.nprice=0)
into :PRICE0;
/*тепеть в зависмости от скидки вычесляем цену ...*/
if (Discounttype=2) then
PRICE=price0-price;
if (Discounttype=1) then
PRICE=price0-(price0*price/100);
end
suspend;
end
end
← →
Johnmen © (2005-02-17 12:27) [2]Совет пока один - привести исчерпывающие исх.данные :)
← →
Johnmen © (2005-02-17 12:28) [3]Ну ты телепат !
:)
← →
Rule © (2005-02-17 12:29) [4]при значении входного параметра равного 0 выдет фигню, тоесть все цены равны первой попавшейся цене ... а при другом значении всё нормально
есть подозрение, что входной параметр, равный 0 неправильно интерпретируется ...
может кто встречался с такой проблеммой ?
← →
Rule © (2005-02-17 12:30) [5]Johnmen © (17.02.05 12:28) [3]
изредка просто сам отвечаю на ворпосы :-)
← →
Rule © (2005-02-17 12:31) [6]так самое интересное, что в режиме отладки (ИБЭксперт) всё работает нормально, а вот при выхове из СКЛ, неправильные данные ...
может оптимизатор чегото ломает ?
← →
Johnmen © (2005-02-17 12:32) [7]1. здесь if (Discounttype!=0) then
я бы такif (Discounttype NOT NULL) AND (Discounttype<>0) then
← →
Rule © (2005-02-17 12:36) [8]Johnmen © (17.02.05 12:32) [7]
ну Discounttype не может быть равен нулл, так как в атрибутах поля стоят не нулевое и значени по умолчанию равное 0
← →
Rule © (2005-02-17 12:37) [9]для конечно полноты картины скрипт таблиц:
таблица с топливом:
/******************************************************************************/
/*** Generated by IBExpert 17.02.2005 11:36:43 ***/
/******************************************************************************/
SET SQL DIALECT 3;
SET NAMES WIN1251;
/******************************************************************************/
/*** Tables ***/
/******************************************************************************/
CREATE GENERATOR GEN_FUEL_ID;
CREATE TABLE FUEL (
ID INTEGER NOT NULL,
NAME VARCHAR(20),
AACTIVE CHAR(1) DEFAULT "t"
);
/******************************************************************************/
/*** Primary Keys ***/
/******************************************************************************/
ALTER TABLE FUEL ADD CONSTRAINT PK_FUEL PRIMARY KEY (ID);
/******************************************************************************/
/*** Triggers ***/
/******************************************************************************/
SET TERM ^ ;
/* Trigger: FUEL_BI */
CREATE TRIGGER FUEL_BI FOR FUEL
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(GEN_FUEL_ID,1);
END
^
SET TERM ; ^
/* Fields descriptions */
DESCRIBE FIELD AACTIVE TABLE FUEL
"активность карточки, если карточка активна, то ""t""
""f"" - если не активная";
/******************************************************************************/
/*** Privileges ***/
/******************************************************************************/
/* Privileges of procedures */
GRANT SELECT ON FUEL TO PROCEDURE "show_balans";
← →
Rule © (2005-02-17 12:38) [10]таблица изменения цен на топливо:
/******************************************************************************/
/*** Generated by IBExpert 17.02.2005 11:38:29 ***/
/******************************************************************************/
SET SQL DIALECT 3;
SET NAMES WIN1251;
/******************************************************************************/
/*** Tables ***/
/******************************************************************************/
CREATE GENERATOR GEN_PRICEFUEL_ID;
CREATE TABLE PRICEFUEL (
ID INTEGER NOT NULL,
ID_FUEL INTEGER,
NPRICE SMALLINT,
PRICE NUMERIC(7,2),
ADATIME TIMESTAMP DEFAULT "NOW",
ADATIMEF TIMESTAMP,
DISCOUNTTYPE SMALLINT DEFAULT 0
);
/******************************************************************************/
/*** Primary Keys ***/
/******************************************************************************/
ALTER TABLE PRICEFUEL ADD CONSTRAINT PK_PRICEFUEL PRIMARY KEY (ID);
/******************************************************************************/
/*** Foreign Keys ***/
/******************************************************************************/
ALTER TABLE PRICEFUEL ADD CONSTRAINT FK_PRICEFUEL FOREIGN KEY (ID_FUEL) REFERENCES FUEL (ID) ON UPDATE CASCADE;
/******************************************************************************/
/*** Triggers ***/
/******************************************************************************/
SET TERM ^ ;
/* Trigger: PRICEFUEL_AU */
CREATE TRIGGER PRICEFUEL_AU FOR PRICEFUEL
ACTIVE AFTER UPDATE POSITION 0
as
begin
/*меняем нестеловские цены на стелловские*/
if ((old.nprice=0) and (new.adatimef is not null)) then
update pricefuel set
adatimef=new.adatimef
where adatimef is null
and nprice<>0;
end
^
/* Trigger: PRICEFUEL_BI */
CREATE TRIGGER PRICEFUEL_BI FOR PRICEFUEL
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.ID IS NULL) THEN
NEW.ID = GEN_ID(GEN_PRICEFUEL_ID,1);
END
^
SET TERM ; ^
/* Fields descriptions */
DESCRIBE FIELD ADATIME TABLE PRICEFUEL
"Теоретическое время и дата активации цены, выставляется бухгалтером";
DESCRIBE FIELD ADATIMEF TABLE PRICEFUEL
"Фактическое время и дата изменения цены, тоесть когда эта цена была залита в кассовый аппарат оператором";
DESCRIBE FIELD DISCOUNTTYPE TABLE PRICEFUEL
"тип скидки по цене
0 - абсолютная цена
1 - процентная скидка
2 - абсолютная скидка";
/******************************************************************************/
/*** Privileges ***/
/******************************************************************************/
← →
Rule © (2005-02-17 12:39) [11]ну и сами данные:
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (54, 10001, 0, 1.15, "2005-02-07 21:55:22", "2005-02-15 18:45:47", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (55, 10002, 0, 1.2, "2005-02-07 21:55:45", "2005-02-15 18:45:47", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (27, 10003, 0, 2.5, "2004-11-30 13:40:03", "2004-12-14 14:59:08", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (28, 10002, 0, 2.3, "2004-11-30 13:40:43", "2004-12-14 14:59:08", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (29, 10004, 0, 3, "2004-12-14 14:53:33", "2004-12-14 14:59:08", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (30, 10001, 0, 1, "2005-01-26 15:09:30", "2005-01-26 22:38:27", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (35, 10001, 0, 1.1, "2005-02-03 16:29:13", "2005-02-03 16:56:06", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (31, 10002, 0, 2, "2005-01-26 15:09:26", "2005-01-26 22:38:27", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (36, 10002, 0, 1.2, "2005-02-03 16:29:30", "2005-02-03 16:56:06", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (37, 10003, 0, 1.3, "2005-02-03 16:29:30", "2005-02-15 18:45:47", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (38, 10004, 0, 1.4, "2005-02-03 16:29:30", "2005-02-03 16:56:06", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (33, 10003, 0, 3, "2005-01-26 15:13:33", "2005-01-26 22:38:27", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (34, 10004, 0, 4, "2005-01-26 15:20:34", "2005-01-26 22:38:27", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (39, 10001, 0, 1.15, "2005-02-03 16:58:32", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (40, 10004, 0, 1.45, "2005-02-03 16:58:32", "2005-02-15 18:45:47", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (41, 10001, 2, 1.17, "2005-02-05 19:18:13", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (42, 10002, 0, 1.12, "2005-02-05 19:18:13", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (43, 10003, 2, 1.17, "2005-02-05 19:18:13", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (44, 10004, 2, 1.27, "2005-02-05 19:18:13", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (45, 10001, 2, 1.42, "2005-02-05 19:21:01", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (46, 10002, 2, 1.17, "2005-02-05 19:22:59", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (47, 10003, 2, 1.27, "2005-02-05 19:22:59", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (48, 10004, 2, 1.42, "2005-02-05 19:22:59", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (49, 10001, 2, 1.12, "2005-02-05 19:22:59", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (50, 10001, 1, 1.13, "2005-02-05 21:00:13", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (51, 10002, 1, 1.18, "2005-02-05 21:00:13", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (52, 10003, 1, 1.28, "2005-02-05 21:00:13", "2005-02-03 17:02:03", 0);
INSERT INTO PRICEFUEL (ID, ID_FUEL, NPRICE, PRICE, ADATIME, ADATIMEF, DISCOUNTTYPE) VALUES (53, 10004, 1, 1.43, "2005-02-05 21:00:13", "2005-02-03 17:02:03", 0);
COMMIT WORK;
← →
Rule © (2005-02-17 12:40) [12]ну и наконец данны из таблицы по топливу ...
INSERT INTO FUEL (ID, NAME, AACTIVE) VALUES (10001, "ДП", "t");
INSERT INTO FUEL (ID, NAME, AACTIVE) VALUES (10002, "А-76", "t");
INSERT INTO FUEL (ID, NAME, AACTIVE) VALUES (10003, "А-92", "t");
INSERT INTO FUEL (ID, NAME, AACTIVE) VALUES (10004, "А-95", "t");
COMMIT WORK;
← →
Rule © (2005-02-17 12:42) [13]ну если надо описать логику работы фрагменты, то
в таблице с топливом хранится номенклатура по топливу.... тут помоему придельно понятно ....
← →
Reindeer Moss Eater © (2005-02-17 12:46) [14]ну Discounttype не может быть равен нулл, так как в атрибутах поля стоят не нулевое и значени по умолчанию равное 0
Это еще почему?
Default срабатывает когда в инсерте поле не перечислено.
Тогда туда попадет значение Default.
Если же поле перечислено в инсерте, то в него попадет что вставляют. В том числе и null.
← →
Johnmen © (2005-02-17 12:53) [15]Возможно, надо так
2.select a.price, a.adatime, a.discounttype
from pricefuel a
where a.id_fuel=:idfuel
and a.nprice=:nprice
and a.adatime=(select max(b.adatime) from pricefuel b
where b.id_fuel=a.id_fuel)
3.select a.price
from pricefuel a
where a.id_fuel=:idfuel
and a.nprice=0
and a.adatime=(select max(b.adatime) from pricefuel b
where b.id_fuel=a.id_fuel)
← →
Deniz (2005-02-17 13:06) [16]Так вроде правильно работает
Проверил IBExpert 2005.02.13 FB 1.5.2
← →
Rule © (2005-02-17 13:13) [17]единственное поле, это поле Эктив, которое является флагом того, что на этой заправке (речье идет про заправки) присутствует такой вид топлива ... так как номенклатура общая и неизменная ....
вторая таблица - это динамика изменения цен на топливо
← →
Rule © (2005-02-17 13:16) [18]Reindeer Moss Eater © (17.02.05 12:46) [14]
я сверху писал, что в атрибутах поля стоит "нот нулл", что исключает твою теорию ... но вообщето не в этом вопрос
← →
Deniz (2005-02-17 13:18) [19]>Reindeer Moss Eater © (17.02.05 12:46) [14]
Если же поле перечислено в инсерте, то в него попадет что вставляют. В том числе и null.
Null точно не попадет по условию
Rule © (17.02.05 12:36) [8]
...
так как в атрибутах поля стоят не нулевое и значени по умолчанию равное 0
Но что-то условие не канает с реальностью
CREATE TABLE PRICEFUEL (
ID INTEGER NOT NULL,
ID_FUEL INTEGER,
NPRICE SMALLINT,
PRICE NUMERIC(7,2),
ADATIME TIMESTAMP DEFAULT "NOW",
ADATIMEF TIMESTAMP,
DISCOUNTTYPE SMALLINT DEFAULT 0
);
← →
Rule © (2005-02-17 13:19) [20]Johnmen © (17.02.05 12:53) [15]
так вообще не работает ...
← →
Rule © (2005-02-17 13:21) [21]Deniz (17.02.05 13:18) [19]
убрал это условие для отладки .. чтоб лишних ошибок не возникало, а проанализировать результаты можно было бы в ручную ...
← →
Rule © (2005-02-17 13:22) [22]Deniz (17.02.05 13:06) [16]
а ты данные вствил те что у меня, если да, то у тебя по нулевой цене должно возвращать 1.15 на все виды топлива ...
← →
Johnmen © (2005-02-17 13:24) [23]>Rule © (17.02.05 13:19) [20]
>так вообще не работает ...
Не может быть.
И ещё один момент - эти запросы должны возвращать ЕДИНСТВЕННУЮ запись...
← →
Deniz (2005-02-17 13:27) [24]Так ты покажи что получаешь в неправильном варианте, а что хочешь получить
← →
Rule © (2005-02-17 13:28) [25]Johnmen © (17.02.05 12:53) [15]
ХАААА, вруу, точно заработало .....
а можно поинтересоваться почему тут возникает такая непонятка, хотелось бы объяснить такое поведение ...
← →
Deniz (2005-02-17 13:28) [26]>Johnmen © (17.02.05 13:24) [23]
Нет по кол-ву записей в fuel, в данном примере 4
← →
Rule © (2005-02-17 13:32) [27]Deniz (17.02.05 13:27) [24]
получались такие результаты
IDFUEL NAME PRICE ADATIME
10 001 ДП 1,15 07.02.2005 21:55
10 002 А-76 1,15 07.02.2005 21:55
10 003 А-92 1,15 07.02.2005 21:55
10 004 А-95 1,15 07.02.2005 21:55
а надо было вот такие :
IDFUEL NAME PRICE ADATIME
10 001 ДП 1,15 07.02.2005 21:55
10 002 А-76 1,2 07.02.2005 21:55
10 003 А-92 1,3 03.02.2005 16:29
10 004 А-95 1,45 03.02.2005 16:58
причем неправильные резульатты выдавались только при нелевом входном параметре
← →
Rule © (2005-02-17 13:33) [28]Johnmen © (17.02.05 13:24) [23]
Не может быть.
И ещё один момент - эти запросы должны возвращать ЕДИНСТВЕННУЮ запись...
возвращают, это понятно иначе будет ругаться мультиплай ин чегототам селект :)
огромное спасибо :-)
← →
Rule © (2005-02-17 13:36) [29]Deniz (17.02.05 13:28) [26]
нет, по логике эти запросы выбирают последнюю запись по дате определенного вида топлива и номера цены (0 - это стелловская цена, тоесть базовая)
← →
Deniz (2005-02-17 13:38) [30]Оно так и выдает и при вызове и пошагово
IDFUEL NAME PRICE ADATIME
10001 1,15 07.02.2005 21:55:22
10002 1,2 07.02.2005 21:55:45
10003 1,3 03.02.2005 16:29:30
10004 1,45 03.02.2005 16:58:32
Name не заполнил
← →
Deniz (2005-02-17 13:40) [31]>Rule © (17.02.05 13:36) [29]
Сори это я вопрос неправильно прочитал, все правильно только 1 запись
← →
Johnmen © (2005-02-17 13:47) [32]>Rule © (17.02.05 13:28) [25]
>а можно поинтересоваться почему тут возникает такая непонятка,
>хотелось бы объяснить такое поведение ...
Вобщем, твой запрос и тот, который я привел, не эквивалентны.
Мною приведенный точно отвечает трубуемым условиям, не зависимо от данных, которые в таблицах. Твой - зависит.
Мне сложно обьяснить это на бумаге... Могу только голосом...:)
PS
Один из моментов - подзапрос в твоём варианте выполняется 1 раз, в моём - на каждую запись основного.
← →
Rule © (2005-02-17 14:04) [33]Johnmen © (17.02.05 13:47) [32]
понятно, спасибо за разьяснение ...
подзапрос я понял это типа
and a.adatime=(select max(b.adatime) from pricefuel b
where b.id_fuel=a.id_fuel)
а почему у меня один раз ... должно же быть под каждую запись отдельно, и почему в пошаге выполняется как надо ?
← →
Rule © (2005-02-17 14:04) [34]Deniz (17.02.05 13:38) [30]
хм ... интересно ...а у меня при вызове то что я написал выше ...
← →
Deniz (2005-02-17 14:39) [35]>Rule © (17.02.05 14:04) [34]
А попробуй сам на пустой базе скрипт запустить и потом посмотреть на результаты работы процедуры
← →
Rule © (2005-02-17 15:09) [36]Deniz (17.02.05 14:39) [35]
ну оно все получилось как посоветовал
Johnmen © (17.02.05 12:53) [15]
а на пустой базе позже проверю, уже для интереса, хотя мне кажется что результат тотже
← →
Johnmen © (2005-02-17 15:18) [37]>Rule © (17.02.05 14:04) [33]
>подзапрос я понял это типа
Да.
>а почему у меня один раз
Потому, что в подзапросе нет никаких ссылок на основной...
← →
Deniz (2005-02-17 15:33) [38]>Johnmen
А смысл выполнять каждый раз подзапрос, если в основном мы сразу отбираем по a.id_fuel=:idfuel, т.е. в главном запросе в a.id_fuel всегда будет одно значение и соот-но в подзапрос будет передаваться только одно значение?
И в этом случае накладные расходы на сервере меньше и результат должен быть одинаковый.
← →
Rule © (2005-02-17 15:39) [39]Johnmen © (17.02.05 15:18) [37]
понял ... всё понятно
← →
Rule © (2005-02-17 15:40) [40]Johnmen © (17.02.05 15:18) [37]
огромное спасибо за подсказку
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2005.03.20;
Скачать: [xml.tar.bz2];
Память: 0.58 MB
Время: 0.057 c