Страница 1 из 1

Не обновляются данные в таблице из ХП

Добавлено: 19 апр 2006, 14:09
koren
Firebird 1.5.3
Есть таблица

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

SET SQL DIALECT 3;

SET NAMES WIN1251;
CREATE TABLE GOODS (
    ID         CHAR(13) NOT NULL,
    NAME       VARCHAR(50),
    VLOG       INTEGER,
    COST       DOUBLE PRECISION DEFAULT 0 NOT NULL
);
ALTER TABLE GOODS ADD CONSTRAINT PK_GOODS PRIMARY KEY (ID);


Есть порцедура
CREATE PROCEDURE INSTAL_PRICE (
    ID_GOOD CHAR(13),
    NEW_COST DOUBLE PRECISION,
    D_PRICE DATE)
AS
DECLARE VARIABLE S_COST DOUBLE PRECISION;
begin

    for select goods.cost from goods where goods.id = :id_good
    into :s_cost
    do begin
        if  (s_cost <> new_cost) then
        begin
            update goods set cost = :new_cost where (goods.id = :id_good);
        end
        exit;
    end
Вызов производится из 1с
Соединение = СоздатьОбъект("ADODB.Connection");
Cоединение.ConnectionString = "driver={Firebird/InterBase(r) driver};server=C:\Program Files\Firebird\Firebird_1_5\bin\fbserver.exe;uid=SYSDBA;pwd=masterkey;database=D:\FB_Base\BOOK_PRICE.FDB;";
Соединение.Open(Соединение.ConnectionString);
Комманда = СоздатьОбъект("ADODB.Command");
Комманда.ActiveConnection = Соединение;


Выборка документов и установка последней цены в таблице GOODS производится с помощью ХП
Комманда.CommandText = "INSERT INTO goods VALUES ('"+ИдОбТов+"'"+","+"'"+Лев(Док.Номенклатура.Наименование, 50)+"',"+Док.Номенклатура.ОсновнаяЕдиница.Коэффициент+",0"+",0"+")";
Комманда.Execute();
Если такой товар есть то FB сам проконтролирует наличие записи по ID (PK)
Комманда.CommandText = "EXECUTE PROCEDURE INSTAL_PRICE('"+ИдОбТов+"'"+","+"'"+Док.Цена+"'"+","+"'"+Док.ДатаДок+"'"+")";
Комманда.Execute();

Обновление таблицы происходит, но почему-то не всех позиций, некоторые остаются с нулевой ценой. Подключение к серверу из 1с всего одно. В чем может быть проблема.

Добавлено: 19 апр 2006, 14:22
Ivan_Pisarevsky
В одинэсе я не силен, но почему бы не селектить из процедуры, вместо экзекута? и из процедуры можно вернуть, к примеру, кол-во проапдеченых записей.

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

Добавлено: 19 апр 2006, 14:38
kdv
значит s_cost временами бывает null. добавь проверку

if ((s_cost <> new_cost) or (s_cost is null)) then

Добавлено: 19 апр 2006, 14:39
Merlin
Причем не с копейкой, а с абс(копейкой). Но здесь вообще-то не про это, про это он в следующий раз спросил бы. Он цену ведь не с нулём сравнивает, а с параметром на неравенство, то есть может проапдейтить нечаянно лишнее, уже установленное, отличающееся в последнем разряде, большой беды не будет. Здесь имхо в символьном ID дело. То ли регистры каких-то символов у параметра и полей в пропущенных записях разные, то ли непечатные символы либо в параметре либо в базе на хвостах.

Добавлено: 19 апр 2006, 15:52
koren
Заменил EXECUTE на SELECT, убрал лишние пробелы справа в ID, убрал пока проверку IF, чтоб наверняка. Вообще перестало работать, т.е. COST по нулям.

Добавлено: 19 апр 2006, 16:01
Dimitry Sibiryakov
Ну естественно. Ты же сам завершаешь процедуру на первой же выбранной записи. Или что там по-твоему делает exit?

Добавлено: 19 апр 2006, 16:04
koren
Извините забыл дописать. Exit в процедуре заменил на SUSPEND.

Добавлено: 20 апр 2006, 08:23
Ivan_Pisarevsky
koren писал(а):Заменил EXECUTE на SELECT, убрал лишние пробелы справа в ID, убрал пока проверку IF, чтоб наверняка. Вообще перестало работать, т.е. COST по нулям.
Давай код, чего ты там наизменял, потому как первоначально у тебя цикл for select и безусловный выход после первой записи, он и не должен проапдейтить больше одной записи. :)

Добавлено: 20 апр 2006, 10:59
koren

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

begin
    count_filds = 0;
    for select goods.cost from goods where goods.id = :id_good
    into :s_cost
    do begin
         update goods set cost = :new_cost where (goods.id = :id_good);
         count_filds = count_filds + 1;
        suspend;
    end


end
Вообще по смуслу одну запись обновить и необходимо, ID_GOOD в селекте первичный ключ таблицы GOODS и там не должно быть более одной записи

Добавлено: 20 апр 2006, 13:45
Dimitry Sibiryakov
А где заголовок процедуры? А способ вызова точно SELECT? А транзакцию ты потом коммитишь? А в какой транзакции смотришь были ли изменения (параметры)? А коммитишь ли ее? В-общем, рассказывай как ты дошел до жизни такой что не срабатывают простейшие запросы.
Кстати, может ты ей просто передаешь неверный ig_good поэтому она, естественно, ничего не выбирает и ничего не апдейтит.

Добавлено: 20 апр 2006, 13:50
Ivan_Pisarevsky
У тебя процедура, по идее вернет нарастающим итогом от 1 и до N набор данных, где N и будет число обработанных записей. Поставь саспенд после цикла.

И вообще чего тут путано все... в принципе процедура должна проапдейтить одну запись, нафиг тогда фор селект??? или апдейтить надо всю таблицу?