Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Новый топик    Ответить
 Ошибки при создании хранимой процедуры DB2  [new]
Shambler-AdMec
Member

Откуда:
Сообщений: 31
Приветствую.

Исходные данные: стаж работы с DB2 практически отсутствует, однако появилась необходимость в создании хранимой процедуры следующего вида:

CREATE PROCEDURE DB2ADMIN.ROUND (IN IP INTEGER, IN A INTEGER, IN Y INTEGER, IN Q INTEGER)
LANGUAGE SQL
DYNAMIC RESULT SETS 0
CONTAINS SQL
NOT DETERMINISTIC
NO EXTERNAL ACTION

BEGIN
DECLARE result decimal(10,2);
DECLARE f decimal(10,2);
DECLARE s decimal(10,2);
 
DECLARE Mach CURSOR FOR 
SELECT value from db2admin.reports where id_param = :IP and id_st_prm < 23 order by id_st_prm desc;
 
 SET result=0;
 SET f=0;
 SET s=0;

 OPEN Mach;

 FETCH FROM Mach INTO f;
  FETCH FROM Mach INTO s;
   result=f/s;
   trunc(result,2);

INSERT INTO DB2ADMIN.REPORTS (ID_PARAM, ID_ST_PRM, VALUE, AREA, YEAR, QUARTER) VALUES (:IP, '23', 'result', :A, :Y, :Q);
COMMIT;
    
CLOSE Mach;
END


В процессе написания пользовался данным документом из справочника по DB2. Процедура получает некие значения из-вне при помощи IN параметров, курсор Mach выбирает требуемые для расчета данные из таблицы БД, затем при помощи FETCH выбранные значения помещаются в переменные, после чего производится расчет. (Запрос SQL построен так, чтобы выводить ровно 2 значения из одного столбца, то есть каждый fetch берет единственное значение из строки и передает его в переменную). Вывод посчитанного осуществляется через INSERT.

Надеюсь, не запутал вас этим изложением.
Проблема: при попытке ввести эту команду в Command Center (центр управления-нужная нам бд-запрос) приводит к невообразимо длинному списку ошибок:

BEGIN
DECLARE result decimal(10,2) default 0
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "END-OF-STATEMENT" was found following "imal(10,
2) default 0".  Expected tokens may include:  "<psm_semicolon>".  LINE 
NUMBER=6.  SQLSTATE=42601

DECLARE f decimal(10,2)
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "DECLARE f decimal" was found following 
"BEGIN-OF-STATEMENT".  Expected tokens may include:  "<values>".  LINE 
NUMBER=1.  SQLSTATE=42601

DECLARE	s decimal(10,2)
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "DECLARE s decimal" was found following 
"BEGIN-OF-STATEMENT".  Expected tokens may include:  "<values>".  LINE 
NUMBER=1.  SQLSTATE=42601

DECLARE Mach CURSOR FOR SELECT value from db2admin.reports where id_param = :IP and id_st_prm < 23 order by id_st_prm desc
DB20000I  The SQL command completed successfully.

SET result=0
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0206N  "RESULT" is not valid in the context where it is used.  
SQLSTATE=42703

SET f=0
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0206N  "F" is not valid in the context where it is used.  SQLSTATE=42703

SET s=0
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0206N  "S" is not valid in the context where it is used.  SQLSTATE=42703

OPEN Mach
DB21031E  The SQL statement using the cursor "MACH" ("SQLCUR1") returned:
SQL0313N  The number of host variables in the EXECUTE or OPEN statement is not 
equal to the number of values required.  SQLSTATE=07004

FETCH FROM Mach INTO f
SQL0104N  An unexpected token "INTO" was found following "<identifier>".  
Expected tokens may include:  "END-OF-STATEMENT".  SQLSTATE=42601

FETCH FROM Mach INTO s
SQL0104N  An unexpected token "INTO" was found following "<identifier>".  
Expected tokens may include:  "END-OF-STATEMENT".  SQLSTATE=42601

result=f/s
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "result" was found following 
"BEGIN-OF-STATEMENT".  Expected tokens may include:  "<variable_set>".  
SQLSTATE=42601

trunc(result,2)
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "(result,2)" was found following "trunc".  
Expected tokens may include:  "<space>".  SQLSTATE=42601

INSERT INTO DB2ADMIN.REPORTS (ID_PARAM, ID_ST_PRM, VALUE, AREA, YEAR, QUARTER) VALUES (:IP, '23', 'result', :A, :Y, :Q)
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0313N  The number of host variables in the EXECUTE or OPEN statement is not 
equal to the number of values required.  SQLSTATE=07004

COMMIT
DB20000I  The SQL command completed successfully.

CLOSE Mach
DB21030E  The cursor "MACH" has not been opened.

END
DB21034E  The command was processed as an SQL statement because it was not a 
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "END-OF-STATEMENT" was found following "END".  
Expected tokens may include:  "JOIN <joined_table>".  SQLSTATE=42601

SQL0104N  An unexpected token "END-OF-STATEMENT" was found following "END".  Expected tokens may include:  "JOIN <joined_table>                              ".


Что сделано:
1. Попытки изменить знак разделителя с ; на @ или даже # приводят к аналогичным ошибкам.
2. Использование командной строки (clp) с параметрами db2 -tvf c:\rnd2.txt показывает аналогичный результат (рнд2.тхт - файл, где хранится текст процедуры представленный выше). ну разве что командная строка после списка ошибок говорит, что sql команда выполнена успешна, все здорово, босс! И да, курсор mach не был открыт

Собственно, текст процедуры написан в соответствии с документацией, показан знающим (не то что я) людям и в целом одобрен. Кроме того, ради эксперимента попробовал ввести заново и выполнить уже имеющиеся в бд хранимые процедуры - проблема та же - ругань на наличие end-of-statement (хотя по логике вещей, ему там самое место) итд.

Условия:
============================================================
О среде инструментов управления DB2
============================================================
Уровень инструментов управления DB2:
Идентификатор продукта SQL08023
Идентификатор уровня 03040106
Уровень DB2 v8.1.10.812
Уровень компиляции s050811
PTF WR21362
============================================================
Комплект разработки Java (JDK):
Уровень IBM Corporation 1.4.1
============================================================

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

Или я чего-то не знаю, что должен был бы... Подскажите, куда смотреть и где можно найти более полную информацию по написанию хранимок.
5 апр 13, 11:43    [14139281]     Ответить | Цитировать Сообщить модератору
 Re: Ошибки при создании хранимой процедуры DB2  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4946
Shambler-AdMec,

Здравствуйте.

Очень много ошибок.

В конце процедуры надо ставить символ разделитель (например, @), отличный от ';' и указывать, что вы его используете.
В Command Center это поле Statement Termination Character внизу окна.
В CLP это -td@, а не -t.

Про доступные конструкции надо смотреть в зависимости от версии db2 в информационном центре для этой версии.
SQL Routines для 8.2

По коду:
* CONTAINS SQL заменить на READS SQL - вы используете SQL команды SELECT, INSERT.
* убрать везде ':' перед именами параметров
*
result=f/s;
trunc(result,2);

Присваивания делаются в операторе SET, а не просто так.
Результат trunc вообще не присваивается ничему.
Наверное лучше:

SET result = trunc(f/s, 2);

* COMMIT
Без особой надобности в процедере не надо делать, это обычно забота вызывающего приложения.
Но если уж делаете, то закройте сначала курсор, а то на 'CLOSE Mach' после 'COMMIT' поймаете ошибку.
5 апр 13, 15:00    [14140806]     Ответить | Цитировать Сообщить модератору
 Re: Ошибки при создании хранимой процедуры DB2  [new]
Shambler-AdMec
Member

Откуда:
Сообщений: 31
Mark Barinstein,

премного благодарен за указанные ошибки и данные вами советы. Буду осваивать и делать
5 апр 13, 16:00    [14141226]     Ответить | Цитировать Сообщить модератору
 Re: Ошибки при создании хранимой процедуры DB2  [new]
Shambler-AdMec
Member

Откуда:
Сообщений: 31
В конечном итоге получилось следующее:

CREATE PROCEDURE DB2BUDGET.ROUND (IN IP INTEGER, IN A INTEGER, IN Y INTEGER, IN Q INTEGER)
LANGUAGE SQL
BEGIN

DECLARE result decimal(10,2);
DECLARE f decimal(10,2);
DECLARE	s decimal(10,2);
DECLARE Mach CURSOR FOR
SELECT value from db2budget.reports where id_param = IP and id_st_prm < 23 order by id_st_prm desc;
 SET result=0;
 SET f=0;
 SET s=0;
 OPEN Mach;
 FETCH FROM Mach INTO f;
  FETCH FROM Mach INTO s;
   SET result=trunc(f/s,2);
INSERT INTO DB2BUDGET.REPORTS (ID_PARAM, ID_ST_PRM, VALUE, AREA, YEAR, QUARTER) VALUES (IP, '23', 'result', A, Y, Q);
CLOSE Mach;
COMMIT;
END
@


Запустил через командную строку в таком виде:

db2 -td@ -vf c:\rnd2.txt

READS SQL выдавал ошибку и хотел вместо "BEGIN" некий токен "DATA", решил попробовать его удалить - все, процедура создалась
Mark Barinstein, спасибо Вам =)
8 апр 13, 10:00    [14149693]     Ответить | Цитировать Сообщить модератору
 Re: Ошибки при создании хранимой процедуры DB2  [new]
CawaSPb
Member

Откуда: Питер/Москва/Wroclaw
Сообщений: 1091
Mark Barinstein
По коду:
* CONTAINS SQL заменить на READS SQL - вы используете SQL команды SELECT, INSERT.


Небольшая поправка. CONTAINS SQL заменить на MODIFIES SQL DATA (или убрать вовсе), там INSERT есть.
8 апр 13, 11:10    [14150068]     Ответить | Цитировать Сообщить модератору
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Ответить