FB 2.x WHERE CURSOR OF

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
armagedon2007
Сообщения: 44
Зарегистрирован: 14 мар 2008, 21:01

FB 2.x WHERE CURSOR OF

Сообщение armagedon2007 » 14 мар 2008, 21:45

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

FOR SELECT Field1 FROM Table
  WHERE Field1 = 10
  FOR UPDATE
  INTO :VAR AS CURSOR TTT
  DO BEGIN
    UPDATE Table SET
      Field1 = Field1 + 100
    WHERE CURRENT OF TTT;
  END
ругается на то? что курсор "TTT" не для update-a
в FB 1.5 все работает даже без сточки FOR UPDATE

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 15 мар 2008, 16:31

ну а более точный текст ошибки дядя ваня приводить будет ?

armagedon2007
Сообщения: 44
Зарегистрирован: 14 мар 2008, 21:01

Сообщение armagedon2007 » 17 мар 2008, 12:13

Dynamic SQL Error.
SQL error code = -510.
Cursor TTT is not updatable.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 17 мар 2008, 13:15

Вероятно, запрос на самом деле выглядит не так?

armagedon2007
Сообщения: 44
Зарегистрирован: 14 мар 2008, 21:01

Сообщение armagedon2007 » 17 мар 2008, 15:02

Запрос выглядит именно так как указоно выше!
И FB 1.5 все работает, а FB 2.0.3 неработает

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 17 мар 2008, 15:31

А у меня работает, что с FOR UPDATE, что без.
Так что ждём с тебя метаданные с данными (тестовыми), на котором можно это повторить.

armagedon2007
Сообщения: 44
Зарегистрирован: 14 мар 2008, 21:01

Сообщение armagedon2007 » 17 мар 2008, 16:20

WildSery писал(а):А у меня работает, что с FOR UPDATE, что без.
Так что ждём с тебя метаданные с данными (тестовыми), на котором можно это повторить.
На какой версии?

armagedon2007
Сообщения: 44
Зарегистрирован: 14 мар 2008, 21:01

Сообщение armagedon2007 » 17 мар 2008, 16:27

Вот процедура

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

CREATE OR ALTER PROCEDURE SET_TEMP_ENTRY(
  DT_ID INTEGER,
  KT_ID INTEGER,
  KOL NUMERIC(18, 3),
  SUMMA NUMERIC(18, 0),
  SKD1 INTEGER,
  SKD2 INTEGER,
  SKD3 INTEGER,
  SKK1 INTEGER,
  SKK2 INTEGER,
  SKK3 INTEGER,
  CAPACITY NUMERIC(18, 3))
AS
DECLARE VARIABLE FLAG INTEGER;
DECLARE VARIABLE R_ID INTEGER;
BEGIN
  FLAG = 0;
  FOR SELECT DISTINCT TEMP_ENTRY.DT_ID FROM TEMP_ENTRY
  WHERE
    (TEMP_ENTRY.DT_ID = :DT_ID) AND
    (TEMP_ENTRY.KT_ID = :KT_ID) AND
    (TEMP_ENTRY.SKD1 = :SKD1) AND
    (TEMP_ENTRY.SKD2 = :SKD2) AND
    (TEMP_ENTRY.SKD3 = :SKD3) AND
    (TEMP_ENTRY.SKK1 = :SKK1) AND
    (TEMP_ENTRY.SKK2 = :SKK2) AND
    (TEMP_ENTRY.SKK3 = :SKK3)
  INTO :R_ID AS CURSOR TTT
  DO BEGIN
    UPDATE TEMP_ENTRY SET
      TEMP_ENTRY.SUMMA = TEMP_ENTRY.SUMMA + :SUMMA,
      TEMP_ENTRY.KOL = TEMP_ENTRY.KOL + :KOL
    WHERE CURRENT OF TTT;
    FLAG = 1;
  END
  IF (:FLAG = 0) THEN BEGIN
    INSERT INTO TEMP_ENTRY (
      DT_ID,
      KT_ID,
      KOL,
      SUMMA,
      SKD1,
      SKD2,
      SKD3,
      SKK1,
      SKK2,
      SKK3,
      CAPACITY)
    VALUES (
      :DT_ID,
      :KT_ID,
      :KOL,
      :SUMMA,
      :SKD1,
      :SKD2,
      :SKD3,
      :SKK1,
      :SKK2,
      :SKK3,
      :CAPACITY);
  END
END
вот DDL таблицы

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

CREATE TABLE TEMP_ENTRY (
  DT_ID DOC_ID DEFAULT 0 NOT NULL,
  KT_ID DOC_ID DEFAULT 0 NOT NULL,
  KOL COUNT_6 NOT NULL,
  SUMMA COST DEFAULT 0 NOT NULL,
  SKD1 DOC_ID DEFAULT 0 NOT NULL,
  SKD2 DOC_ID DEFAULT 0 NOT NULL,
  SKD3 DOC_ID DEFAULT 0 NOT NULL,
  SKK1 DOC_ID DEFAULT 0 NOT NULL,
  SKK2 DOC_ID DEFAULT 0 NOT NULL,
  SKK3 DOC_ID DEFAULT 0 NOT NULL,
  CAPACITY COUNT DEFAULT 0 NOT NULL);


CREATE INDEX IDX_TEMP_ENTRY ON TEMP_ENTRY(DT_ID,KT_ID);

CREATE INDEX IDX_TEMP_ENTRY1 ON TEMP_ENTRY(DT_ID);

CREATE INDEX IDX_TEMP_ENTRY10 ON TEMP_ENTRY(SKD1,SKD2);

CREATE INDEX IDX_TEMP_ENTRY11 ON TEMP_ENTRY(SKK1,SKK2);

CREATE INDEX IDX_TEMP_ENTRY12 ON TEMP_ENTRY(SKD1,SKD2,SKK1,SKK2);

CREATE INDEX IDX_TEMP_ENTRY2 ON TEMP_ENTRY(KT_ID);

CREATE INDEX IDX_TEMP_ENTRY3 ON TEMP_ENTRY(SKD1);

CREATE INDEX IDX_TEMP_ENTRY4 ON TEMP_ENTRY(SKD2);

CREATE INDEX IDX_TEMP_ENTRY5 ON TEMP_ENTRY(SKD3);

CREATE INDEX IDX_TEMP_ENTRY6 ON TEMP_ENTRY(SKK1);

CREATE INDEX IDX_TEMP_ENTRY7 ON TEMP_ENTRY(SKK2);

CREATE INDEX IDX_TEMP_ENTRY8 ON TEMP_ENTRY(SKK3);

CREATE INDEX IDX_TEMP_ENTRY9 ON TEMP_ENTRY(SKD1,SKK1);
ну данные сам попробуй любые залить

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 17 мар 2008, 16:30

armagedon2007 писал(а):Вот процедура

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

  FOR SELECT DISTINCT
...
    UPDATE
    WHERE CURRENT OF
Тоиссь, курсор, типо, спозиционирован эдак тыщ на 5 записей разом. Для апдейту. Ну-ну.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 17 мар 2008, 16:40

Типа как и думал. Запрос не тот.
Правда, я подумал про группировку или join... Но distinct тоже хорош.

armagedon2007
Сообщения: 44
Зарегистрирован: 14 мар 2008, 21:01

Сообщение armagedon2007 » 17 мар 2008, 18:15

Merlin писал(а):
armagedon2007 писал(а):Вот процедура

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

  FOR SELECT DISTINCT
...
    UPDATE
    WHERE CURRENT OF
Тоиссь, курсор, типо, спозиционирован эдак тыщ на 5 записей разом. Для апдейту. Ну-ну.
Спасибо!
На это я даже и не посмотрел.
Ранше было без курсора, потом добавил курсор и приэтов в FB 1.5 работало.
Но запись веравно в таблице только одна. :)

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 18 мар 2008, 06:14

а чем
IF (:FLAG = 0)
лучше
IF (ROW_COUNT=0)
?

Attid
Спец
Сообщения: 377
Зарегистрирован: 14 ноя 2006, 09:58

Сообщение Attid » 18 мар 2008, 13:36

stix-s писал(а):а чем
IF (:FLAG = 0)
лучше
IF (ROW_COUNT=0)
?
в 1,5 на select он всегда возращает 0
может что не так посчитается ?

хотя что-то я об ROW_COUNT первый раз услышал :oops: , но уже исправился =)

stix-s
Заслуженный разработчик
Сообщения: 557
Зарегистрирован: 13 дек 2005, 11:52

Сообщение stix-s » 18 мар 2008, 13:44

Attid писал(а):
в 1,5 на select он всегда возращает 0
может что не так посчитается ?
угу, но я про FB 2, единственно при отладке в IBE казусы возникают :)

Ответить