Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Оператор CASE в теле процедуры / 5 сообщений из 5, страница 1 из 1
20.11.2006, 10:27
    #34140072
SunnyVa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оператор CASE в теле процедуры
При использовании оператора CASE в теле процедуры возникает ошибка - делаю так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
P1: BEGIN
...
        CASE ROUND(RAND()* 6 , 0 )+ 1 
	  WHEN  1  THEN INSERT INTO SESSION.TEMP1 (I) VALUES ( 44 );
	  WHEN  2  THEN UPDATE SESSION.TEMP1 SET I= 44 + 2 ;
	  WHEN  3  THEN SELECT * FROM SESSION.TEMP1;
	  WHEN  4  THEN INSERT INTO SESSION.TEMP1 (I) VALUES ( 44 + 7 );
	  WHEN  5  THEN INSERT INTO SESSION.TEMP1 (I) VALUES ( 44 - 7 );
	  WHEN  6  THEN INSERT INTO SESSION.TEMP1 (I) VALUES (  4  );
	  WHEN  7  THEN UPDATE SESSION.TEMP1 SET I= 0 ;
	END CASE;
...
END P1

Ошибка SQL7032
(работаю с версией DB2 UDB for iSeries (AS/400) V5R3)
Объясните, пожалуйста, почему это происходит?
...
Рейтинг: 0 / 0
20.11.2006, 11:36
    #34140304
SunnyVa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оператор CASE в теле процедуры
сделала так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
P1: BEGIN

DECLARE QSTR VARCHAR( 100 );
...
        CASE ROUND(RAND()* 6 , 0 )+ 1 
	  WHEN  1  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES (44)';
	  WHEN  2  THEN SET QSTR='UPDATE SESSION.TEMP1 SET I=' || ( 44 + 2 );
	  WHEN  3  THEN SET QSTR='SELECT * FROM SESSION.TEMP1';
	  WHEN  4  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES (' || ( 44 + 7 ) || ')';
	  WHEN  5  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES (' || ( 44 - 7 ) || ')';
	  WHEN  6  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES ( 4 )';
	  WHEN  7  THEN SET QSTR='UPDATE SESSION.TEMP1 SET I=0';
	END CASE;

EXECUTE IMMEDIATE QSTR ;
...
END P1


помогло... но правильно ли так делать...
...
Рейтинг: 0 / 0
20.11.2006, 15:39
    #34141308
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оператор CASE в теле процедуры
Не получилось потому что:
1. Надо объявить SESSION.TEMP1 до создания процедуры.
2. Вы не можете написать просто
SELECT * FROM SESSION.TEMP1
эта операция бессмысленна, т.к. не понятно, что вы хотите ей достичь.
Если надо получить значение SESSION.TEMP1.I, то можно сделать что-то типа:
---
P1: BEGIN
DECLARE LI INT ;
...
CASE ROUND(RAND()*6,0)+1
WHEN 1 THEN INSERT INTO SESSION.TEMP1 (I) VALUES (44);
WHEN 2 THEN UPDATE SESSION.TEMP1 SET I=44+2;
WHEN 3 THEN SELECT I INTO LI FROM SESSION.TEMP1 ;
WHEN 4 THEN INSERT INTO SESSION.TEMP1 (I) VALUES (44+7);
WHEN 5 THEN INSERT INTO SESSION.TEMP1 (I) VALUES (44-7);
WHEN 6 THEN INSERT INTO SESSION.TEMP1 (I) VALUES ( 4 );
WHEN 7 THEN UPDATE SESSION.TEMP1 SET I=0;
END CASE;
...
END P1
---
...
Рейтинг: 0 / 0
20.11.2006, 16:39
    #34141557
SunnyVa
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оператор CASE в теле процедуры
временная таблица у меня создается до данного оператора CASE
да я в курсе, что операция SELECT у меня бесмысленна...
просто я пытаюсь реализовать в теле процедуры следующее:
1. процедура должна работать, ну скажем, 2 минуты
за временем работы процедуры я слежу, считывая каждый раз после выполнения какой-либо операции SELECT, UPDATE, INSERT текущее время
2. каждая операция, которая выполняется за указаное время я записываю в специальную таблицу (во сколько был выполнен такой-то DML-опертор)
3. пытаюсь как бы специально выполнить оператор, в данном случае SELECT * FROM SESSION.TEMP1, который изначально ошибочный и поймать данную ошибку - в таблицу записать сообщение о том, что была такая-то ошибка и прерываю процедуру, не смотря на то, что ещё 2 минуты не прошло...

вот собственно зачем мне и был нужен такой CASE...

ошибку ловлю, используя CONTINUE HANDLER:

Код: plaintext
1.
2.
3.
4.
5.
DECLARE ME VARCHAR (  100  ) ;
DECLARE ST VARCHAR (  5  ) ;

DECLARE CONTINUE HANDLER FOR SQLWARNING,SQLEXCEPTION
GET DIAGNOSTICS EXCEPTION  1  ME = MESSAGE_TEXT , ST = RETURNED_SQLSTATE ;

но при использовании данной конструкции
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
CASE ROUND(RAND()* 6 , 0 )+ 1 
	  WHEN  1  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES (44)';
	  WHEN  2  THEN SET QSTR='UPDATE SESSION.TEMP1 SET I=' || ( 44 + 2 );
	  WHEN  3  THEN SET QSTR='SELECT * FROM SESSION.TEMP1';
	  WHEN  4  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES (' || ( 44 + 7 ) || ')';
	  WHEN  5  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES (' || ( 44 - 7 ) || ')';
	  WHEN  6  THEN SET QSTR='INSERT INTO SESSION.TEMP1 (I) VALUES ( 4 )';
	  WHEN  7  THEN SET QSTR='UPDATE SESSION.TEMP1 SET I=0';
	END CASE;

EXECUTE IMMEDIATE QSTR ;
например, не удается с помощью команды GET DIAGNOSTICS CR = ROW_COUNT; узнать сколько было обновлено записей, если в переменной QSTR был запрос на обновление...

Mark, вот так смутно я попыталась Вам объяснить зачем так делала...
вполне возможно, что нужно было делать все как-то по-другому... но пока пришло в голову только это...
...
Рейтинг: 0 / 0
20.11.2006, 17:47
    #34141787
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оператор CASE в теле процедуры
SunnyVaвременная таблица у меня создается до данного оператора CASEЕще раз.
1.
Т.к. вы используете статический SQL, то: чтобы процедура скомпилировалась, вам надо, чтоб эта временная таблица существовала до момента компиляции . И не важно, что в теле процедуры есть ее определение.
2.
Именно потому, что вы используете статический sql, процедура с ошибочной командой у вас просто не скомпилируется.

Если у вас задача - чтоб iSeries "убивал" долгоиграющие запросы, то я уже давал вам ссылку в соседнем топике. Наверное, вы не поняли, как это использовать?

SunnyVaнапример, не удается с помощью команды GET DIAGNOSTICS CR = ROW_COUNT; узнать сколько было обновлено записей, если в переменной QSTR был запрос на обновление...Вот вам пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
create procedure test_upd(in i int, out cnt int)
language sql
BEGIN
declare stmt varchar( 4096 );
declare li int;
set stmt = 
  'declare global temporary table session.test (i int) with replace';
execute immediate stmt;
set li= 0 ;
while (li<i) do
 set stmt = 'insert into session.test values (1)';
 execute immediate stmt;
 set li=li+ 1 ;
end while;
set stmt = 'update session.test set i=2';
execute immediate stmt;
get diagnostics cnt = ROW_COUNT;
END;
Процедура создает временную таблицу, вставляет в нее i записей, а потом их всех обновляет. Возвращает кол-во обновленных записей.
Что возвратит у вас, скажем
Код: plaintext
call test_upd( 5 , ?);
?
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Оператор CASE в теле процедуры / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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