Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Странное поведение при update`е GTT / 14 сообщений из 14, страница 1 из 1
28.03.2016, 16:44
    #39202333
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
Столкнулся с непонятной проблемой.
Есть временная таблица, допустим
Код: sql
1.
2.
3.
4.
CREATE GLOBAL TEMPORARY TABLE TMP (
    FLD1      INTEGER,
    FLD2      INTEGER
) ON COMMIT DELETE ROWS;



В хранимке эта таблица заполняется данными (insert), после чего обрабатывается (update и затем select), что то вроде
Код: sql
1.
2.
update tmp set fld2 = 123 where fld1 = 666;
for select fld1,fld2 from tmp into....


Так вот, если сделать селект обновляемого поля Fld2 перед выполнением апдейта, то в for select попадают необновленные данные для Fld2, но обновленные для Fld1.
WTF? Где новые версии записей поля Fld2?
...
Рейтинг: 0 / 0
28.03.2016, 16:47
    #39202341
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
NaumOffWTF?
Полный лог из isql, плиз, а то непонятно кто на ком стоял.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.03.2016, 16:48
    #39202343
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
NaumOffТак вот, если сделать селект обновляемого поля Fld2 перед выполнением апдейта, то в for select попадают необновленные данные для Fld2, но обновленные для Fld1.

а чего это они должны обновляться перед выполнением update?
...
Рейтинг: 0 / 0
28.03.2016, 16:59
    #39202358
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
Dimitry Sibiryakov,
Работаю в IbExpert`е. Как сделать лог в isql?

Похоже баг какой то. Дело не в селекте. Пробовал сделать селект в переменную и апдейт поля по этой переменной. Не работает. Но если сделать апдейт тупо по литералу, все видится как надо.

Совсем забыл. Firebird 2.5.5 Classic.
...
Рейтинг: 0 / 0
28.03.2016, 17:03
    #39202363
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
NaumOff,

ты полный скрипт покажи. Скорее всего бага в твоём скрипте
...
Рейтинг: 0 / 0
28.03.2016, 17:03
    #39202365
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
Симонов Дениса чего это они должны обновляться перед выполнением update?
Не вижу обновления после update.
Поле Fld2 не обновляется, если новое значение берется из подзапроса или переменной
Например, так не работает:
Код: sql
1.
2.
update tmp set fld2 = (select fld from another_table);
update tmp set fld2 = :value;


С литералом все обновляется.
Код: sql
1.
update tmp set fld2 = 123;
...
Рейтинг: 0 / 0
28.03.2016, 17:05
    #39202366
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
Симонов ДенисNaumOff,

ты полный скрипт покажи. Скорее всего бага в твоём скрипте

Да я все лишнее выкинул, скрипт простейший. Попробую сделать демку.
...
Рейтинг: 0 / 0
28.03.2016, 17:05
    #39202367
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
NaumOff,

воспроизводимый пример в студию
...
Рейтинг: 0 / 0
28.03.2016, 17:14
    #39202376
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
NaumOffНапример, так не работает:
Первый update должен тупо обломиться с ошибкой "multiple rows in singleton select",
поэтому до второго дело даже не доходит. Естественно такой блок и не может работать.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.03.2016, 17:16
    #39202378
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
Симонов Денис,
Вот блин:) Похоже это я где-то накосячил. В демке все работает как надо, буду копать свою хранимку. Прошу прощения за беспокойство.
...
Рейтинг: 0 / 0
28.03.2016, 17:51
    #39202411
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
Dimitry SibiryakovПервый update должен тупо обломиться с ошибкой "multiple rows in singleton select",
поэтому до второго дело даже не доходит. Естественно такой блок и не может работать.

Нее, там агрегат, multiple rows не будет. Да и ошибке я был бы рад, хоть какая то ясность. А тут вроде работает, а результат не тот, что ожидается.
Всю голову себе сломал, не вижу ошибок. Закомментил весь рабочий код, все равно литералом в лоб апдейтит, подзапросом или переменной нет. А ведь между ними в таком контексте нет никакой разницы. У переменной есть значение, подзапрос однозначно возвращает результат.

В демке все работает. Вот набросал, примерно как все выглядит (только полей гораздо больше):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
CREATE GLOBAL TEMPORARY TABLE TMP (
    FLD1  INTEGER,
    FLD2  INTEGER
) ON COMMIT PRESERVE ROWS;

SET TERM ^ ;

CREATE OR ALTER PROCEDURE STRANGE_PROCEDURE
RETURNS (
    FLD1 INTEGER,
    FLD2 INTEGER)
AS
DECLARE VARIABLE Val INTEGER;
BEGIN
  DELETE FROM Tmp;

  INSERT INTO Tmp
  VALUES (1, 2);
  INSERT INTO Tmp
  VALUES (2, 3);
  INSERT INTO Tmp
  VALUES (NULL, 5);
  INSERT INTO Tmp
  VALUES (6, 7);

  --так работает
  UPDATE Tmp
  SET Fld2 = 10
  WHERE Fld1 = 2;

  --а так нет
  Val = (SELECT MAX(Fld2)
         FROM Tmp);

  UPDATE Tmp
  SET Fld2 = :Val
  WHERE Fld1 IS NULL;
  
  --и так тоже нет
  UPDATE Tmp
  SET Fld2 = (SELECT MAX(Fld2)
              FROM Tmp)
  WHERE Fld1 IS NULL;

  FOR SELECT Fld1, Fld2
      FROM Tmp
      INTO :Fld1, :Fld2
  DO
    SUSPEND;
END^

...
Рейтинг: 0 / 0
28.03.2016, 17:57
    #39202414
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
А еще работает вот так:
Код: sql
1.
2.
3.
4.
  Val = 10;
  UPDATE Tmp
  SET Fld2 = :Val
  WHERE Fld1 IS NULL;



То есть переменная = литерал, затем апдейт.
...
Рейтинг: 0 / 0
28.03.2016, 17:57
    #39202416
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
NaumOff--а так нет
А у меня твой пример работает:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SQL> select * from strange_procedure;

         FLD1         FLD2
============ ============
            1            2
            2           10
       <null>           10
            6            7


К чему бы это?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
28.03.2016, 18:39
    #39202459
NaumOff
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Странное поведение при update`е GTT
Dimitry SibiryakovК чему бы это?..

К тому, что косяк в моей хранимке. Нашел ошибку в логике, цикл охватывал лишний блок, для подзапроса попросту уже не было нужных данных и в переменных для апдейта на самом деле сидели null`ы, а литерал он есть литерал, никакой мистики. Кстати, отладчик процедур IbExpert`a здорово подвел, не всегда правильно рассчитывает значения переменных. В сложных ситуациях на него не стоит полагаться.
Огнептица как всегда работает железно.
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Странное поведение при update`е GTT / 14 сообщений из 14, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]