powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Проблема с записью даты в хранимой процедуре !
16 сообщений из 16, страница 1 из 1
Проблема с записью даты в хранимой процедуре !
    #36380553
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день, уважаемые эксперты.
В хранимой процедуре в DB2 версия 8.2 столкнулись с проблемой записи текущей даты и времени, подскажите, пожалуйста.

Кусок процедуры

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
  SET dt=CURRENT TIMESTAMP
  ...
  Insert
    Into tbTest(CurrentDate)
    Values(dt)
  -- дата записывается нормально

  Update tbTest
    Set CurrentDate=dt
    Where (TestID= 1 )
  -- записывается NULL вместо даты


В одной и той же процедуре в зависимости от разных условий производится либо Insert, либо Update в одной и той же таблице.
Параметр dt сделан выходным параметром в процедуре.
В случае Insert все работает корректно.
В случае Update в таблицу записывается NULL и параметр dt возвращает из процедуры "14.09.;310 21:18:05".
Как такое может быть? Параметр dt больше нигде не изменяется после записи SET dt=CURRENT TIMESTAMP
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36380583
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Challenger,

Добрый день.

А нет ли в таблице tbTest поля с именем dt?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36380601
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mark Barinstein, нету

Вот привожу конкретные данные, а не абстрактный тестовый пример

Параметр @CUR_TIMESTAMP на который обращаем внимание

это таблица
Код: plaintext
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.
CREATE TABLE "DB2INST1"."DOC_SYSTEMS"  (
    "DOC_SYS_ID" INTEGER NOT NULL , 
    "DOC_ID_ISOGD" INTEGER NOT NULL , 
    "DOC_SYS_DATE" DATE , 
    "DOC_SYS_NUM" VARCHAR( 512 ) , 
    "DOC_SYS_TYPE" VARCHAR( 512 ) , 
    "DOC_SYSTEM_NAME" VARCHAR( 1000 ) , 
    "DOC_SYS_IS_SOURCE" VARCHAR( 20 ) , 
    "DOC_SYS_XML" VARCHAR( 500 ) , 
    "DOC_SYS_COMMENT" VARCHAR( 1024 ) , 
    "DOC_SYS_COORD" VARCHAR( 400 ) , 
    "DOC_SYS_ADDR" VARCHAR( 2048 ) , 
    "DOC_SYSTEM_ID" VARCHAR( 512 ) , 
    "DOC_SYS_NAME" VARCHAR( 3072 ) , 
    "DOC_PARENT_SYSTEM_NAME" VARCHAR( 1024 ) , 
    "DOC_PARENT_SYSTEM_ID" VARCHAR( 255 ) , 
    "DOC_OBJ_SYS_FUNC" VARCHAR( 1024 ) , 
    "DOC_DATE_UNTIL" DATE , 
    "DOC_STATE" VARCHAR( 200 ) , 
    "DOC_DATE_D" DATE , 
    "INVENTORY_NUM" VARCHAR( 50 ) , 
    "INVENTORY_DATE" DATE , 
    "ISOGD_NUM" VARCHAR( 50 ) , 
    "ISOGD_DATE" DATE , 
    "IS_SHOWN" SMALLINT , 
    "DATE_OF_INSERT" TIMESTAMP , 
    "OBJ_COORD" VARCHAR( 3000 ) )   
   IN "USERSPACE3" ; 

-- DDL Statements for primary key on Table "DB2INST1"."DOC_SYSTEMS"

ALTER TABLE "DB2INST1"."DOC_SYSTEMS" 
 ADD CONSTRAINT "CC1256109530092" PRIMARY KEY
  ("DOC_SYS_ID");

это процедура
Код: plaintext
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.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
CREATE PROCEDURE DB2INST1.DOC_SYSTEM_CREATE (

    OUT @RES INT, --
    OUT @DOC_SYS_ID INT,
    OUT @CUR_TIMESTAMP TIMESTAMP;
    IN @DOC_ID_ISOGD INTEGER,
    IN @DOC_SYSTEM_NAME VARCHAR( 1000 ),
    IN @DOC_SYSTEM_ID VARCHAR( 512 ),
    IN @DOC_SYS_NAME VARCHAR( 3072 ),
    IN @DOC_SYS_TYPE VARCHAR( 512 ),
    IN @DOC_SYS_NUM VARCHAR( 512 ),
    IN @DOC_SYS_DATE DATE,
    IN @DOC_SYS_COORD VARCHAR( 400 ),
    IN @DOC_SYS_ADDR VARCHAR( 2048 ),
    IN @DOC_SYS_COMMENT VARCHAR( 1024 ),
    IN @DOC_SYS_XML VARCHAR( 500 ),
    IN @DOC_SYS_IS_SOURCE VARCHAR( 20 ),
    IN @DOC_PARENT_SYSTEM_NAME VARCHAR( 1024 ),
    IN @DOC_PARENT_SYSTEM_ID VARCHAR( 255 ),
    IN @DOC_OBJ_SYS_FUNC VARCHAR( 1024 )
)

------------------------------------------------------------------------
-- SQL
------------------------------------------------------------------------
P1: BEGIN
    DECLARE SQLCODE INTEGER DEFAULT  0 ;
    DECLARE @OLD_DOC_SYS_ID INTEGER DEFAULT NULL;
    DECLARE CUR_TIMESTAMP TIMESTAMP;
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
   
    
    SET @CUR_TIMESTAMP = current timestamp;
    
     SET @RES = SQLCODE;

    SET @OLD_DOC_SYS_ID = NULL;
    SELECT DOC_SYS_ID
        INTO @OLD_DOC_SYS_ID
        FROM  DB2INST1.DOC_SYSTEMS
        WHERE (DOC_SYSTEM_ID=@DOC_SYSTEM_ID) AND (DOC_SYSTEM_NAME='RONIX')
AND ((DOC_STATE IS NULL) OR (DOC_STATE<>'удален'));

    IF (@OLD_DOC_SYS_ID IS NULL) THEN
        SET @DOC_SYS_ID = NEXT VALUE FOR DB2INST1.DOC_SYS_ID_SEQ;
        INSERT INTO
DB2INST1.DOC_SYSTEMS(DOC_SYS_ID,DOC_SYS_NUM,DOC_SYS_DATE,DOC_SYS_TYPE,DOC_SYSTEM_NAME,
DOC_SYS_IS_SOURCE,DOC_SYS_XML,DOC_SYS_COMMENT,DOC_ID_ISOGD,DOC_SYS_COORD,
DOC_SYS_ADDR,DOC_SYSTEM_ID,DOC_SYS_NAME,DOC_PARENT_SYSTEM_NAME,DOC_PARENT_SYSTEM_ID,DOC_OBJ_SYS_FUNC, DATE_OF_INSERT)

VALUES(@DOC_SYS_ID,@DOC_SYS_NUM,@DOC_SYS_DATE,@DOC_SYS_TYPE,@DOC_SYSTEM_NAME
,

@DOC_SYS_IS_SOURCE,@DOC_SYS_XML,@DOC_SYS_COMMENT,@DOC_ID_ISOGD,@DOC_SYS_COORD,

@DOC_SYS_ADDR,@DOC_SYSTEM_ID,@DOC_SYS_NAME,@DOC_PARENT_SYSTEM_NAME,@DOC_PARENT_SYSTEM_ID,@DOC_OBJ_SYS_FUNC, @CUR_TIMESTAMP);

    ELSE
        DELETE
                FROM DB2INST1.DOCS_PARAM
                WHERE (DOC_SYS_ID=@OLD_DOC_SYS_ID);
        DELETE
                FROM DB2INST1.DOCS_ORG
                WHERE (DOC_SYS_ID=@OLD_DOC_SYS_ID);
        DELETE
                FROM DB2INST1.DOCS_OSN
                WHERE (DOC_SYS_ID=@OLD_DOC_SYS_ID);

        UPDATE DB2INST1.DOC_SYSTEMS
                SET
DOC_SYSTEM_NAME=@DOC_SYSTEM_NAME,DOC_SYS_IS_SOURCE=@DOC_SYS_IS_SOURCE,DOC_SYS_XML=@DOC_SYS_XML,

DOC_SYS_COMMENT=@DOC_SYS_COMMENT,DOC_ID_ISOGD=@DOC_ID_ISOGD,DOC_SYS_COORD=@DOC_SYS_COORD,

DOC_SYS_ADDR=@DOC_SYS_ADDR,DOC_SYSTEM_ID=@DOC_SYSTEM_ID,DOC_SYS_NAME=@DOC_SYS_NAME,

DOC_PARENT_SYSTEM_NAME=@DOC_PARENT_SYSTEM_NAME,DOC_PARENT_SYSTEM_ID=@DOC_PARENT_SYSTEM_ID,DOC_OBJ_SYS_FUNC=@DOC_OBJ_SYS_FUNC,DATE_OF_INSERT=@CUR_TIMESTAMP
                WHERE (DOC_SYS_ID=@OLD_DOC_SYS_ID);
        SET @DOC_SYS_ID=@OLD_DOC_SYS_ID;
    END IF;
    IF (@RES IS NULL) THEN
        SET @RES =  0 ;
    END IF;
    IF (@RES IS NOT NULL AND @RES= 100 ) THEN
        SET @RES =  0 ;
    END IF;
END
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36380729
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
т.е. вы хотите сказать, что остальные поля этим update обновляются, а DATE_OF_INSERT - нет?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36380766
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да остальные поля обновляются,
что-то не так?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36381505
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Challengerда остальные поля обновляются,
что-то не так?Да, код выгладит несколько странно.
Оно работает так, как и должно.
Вы написали обработчик исключений из одного оператора SET:
Код: plaintext
1.
2.
    DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
    SET @CUR_TIMESTAMP = current timestamp;
т.е. присваивание переменной будет происходить только если внутри кода далее произойдёт любое исключение (ошибка или предупреждение).
Такое присваивание, например, будет происходить если:
- select into не вернёт ничего (not found) или вернёт более 1 записи (sqlexception)
- один из delete не удалит ни одной записи

Но если select into вернёт ровно 1 запись, а все delete успешно удалят хотя бы по 1 записи, то присваивание таймстэмпа не сработает.
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36381691
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mark Barinstein, спасибо большое за подсказку,

Как здесь сделать корректно, чтобы присвоение производилось в любом случае?

Насколько я понимаю нужно написать так?
Код: plaintext
1.
2.
3.
4.
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
   SET @RES = SQLCODE;
    
    SET @CUR_TIMESTAMP = current timestamp;
 
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36381877
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, можно так.

Ради интереса: у вас так специально задумано, что если select into вернёт более 1 зиписи, то вставится новая?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36384028
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет наверное еще одна ошибка.
Почему так? Объясните пожалуйста.
Запись должна вставляться только в том случае если нету записей вообще.
@OLD_DOC_SYS_ID будет NULL если несколько записей? Почему?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36384123
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ChallengerЗапись должна вставляться только в том случае если нету записей вообще.
@OLD_DOC_SYS_ID будет NULL если несколько записей? Почему?Потому, что если select into возвращает более 1 записи, то генерируется sqlexception (SQLSTATE 21000) и присваивание не происходит.
У вас определен continue handler для всех sqlexception, т.е. выполнение продолжится со следующего оператора.
А @OLD_DOC_SYS_ID как был NULL до select into, так NULL'ом и останется после него.
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36384296
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получается в нашем случае нужно
Код: plaintext
1.
 DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
изменить на

Код: plaintext
1.
 DECLARE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND

В этом случае, если будет ошибка, то продолжаться выполнение не будет, верно?
В случае exception мне нужно прерывать выполнение процедуры, а не продолжать.

И второй вопрос.
Как корректно проверить существование записи в таблице внутри хранимой процедуры DB2, чтобы при наличии нескольких записей не генерировался Exception?
Через Exists?
Этот трюк который я использую в MsSQL например не генерирует exception. Поэтому я его и здесь не ожидал.
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36384431
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
1. Если вы хотите, чтобы процедура делала атомарные (либо всё, либо ничего) изменения, и при ошибке прекращалось выполнение процедуры, то:
...
P1: BEGIN ATOMIC
...
DECLARE UNDO HANDLER FOR SQLEXCEPTION
SET @RES = SQLCODE;
...
END
2. ChallengerКак корректно проверить существование записи в таблице внутри хранимой процедуры DB2, чтобы при наличии нескольких записей не генерировался Exception?
Через Exists?Проверить можно разными способами.
Вопрос в том, что же вам надо делать, если по условию
Код: plaintext
1.
WHERE (DOC_SYSTEM_ID=@DOC_SYSTEM_ID) AND (DOC_SYSTEM_NAME='RONIX')
AND ((DOC_STATE IS NULL) OR (DOC_STATE<>'удален'))
вернётся несколько записей?
- Прерывать выполнение?
- Продолжать? Тогда что именно делать?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36384738
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я может быть не корректно сформулировал вопрос.
Он не привязан к данной процедуре.
Вопрос следующий.

Как одним запросом проверить, есть ли запись в таблице, а если есть получить идентификатор одной из записей.
Если запись одна, то соответственно ее идентификаторю
В Ms SQL это делалось через переменную.
А как это сделать в DB2?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36384847
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ChallengerКак одним запросом проверить, есть ли запись в таблице, а если есть получить идентификатор одной из записей.
Если запись одна, то соответственно ее идентификаторю
В Ms SQL это делалось через переменную.
А как это сделать в DB2?Что должен возвратить запрос, если заданному условию соответствуют несколько записей?
Например, для таблицы:
tab(id, value) с данными (1, 1), (2, 1) вы выполняете запрос, который вернёт оба идентификатора:
Код: plaintext
1.
2.
3.
4.
5.
select id
from table(values
  ( 1 ,  1 )
, ( 2 ,  1 )
) tab (id, value)
where value= 1 
Как ведёт себя MS SQL, когда результат такого запроса сохраняется в переменную?
Чему будет равно значение этой переменной после такого присваивания?
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36384993
Challenger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mark Barinstein,

синтаксис будет другой немного
select @id=id
from table
where value=1

В переменную @id будет выставлено значение "2" в Вашем примере.
...
Рейтинг: 0 / 0
Проблема с записью даты в хранимой процедуре !
    #36385060
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ради интереса: а почему не "1"?
Есть какие-то правила возвращения значения в таких случаях в MS SQL?

В db2 такой запрос должен возвращать не более 1 строки.
Достигается это например так:
1. первую попавшуюся:
Код: plaintext
select id into @id from ... where ... fetch first  1  row only
2. если надо отдавать предпочтение какой-то строке, то это можно делать с помощью 'order by'.
например:
- с min id:
Код: plaintext
select id into @id from ... where ... order by id fetch first  1  row only
- с max id:
Код: plaintext
select id into @id from ... where ... order by id desc fetch first  1  row only
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Проблема с записью даты в хранимой процедуре !
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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