Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / DB2 CLP и SQL PL / 15 сообщений из 15, страница 1 из 1
10.08.2012, 04:10
    #37911532
Kostya Ilyinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Добрый день - несколько часов уже пытаюсь решить следующую задачку. Дано - массив со строками, допустим имена штатов. Нужно пробежаться по ним и вставить данные в пару таблиц. В Оракле для этих целей сгодится безымянный PL SQL блок, т.е. запускаем sqlplus и пошел

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
DECLARE

BEGIN

INSERT ...
INSERT ...

END
/


и готово. Как мне можно в DB2 не используя функции/процедуры, однократно выполнить нечто подобное. Пробовал:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
BEGIN ATOMIC 
 FOR row AS
    SELECT identifier, type FROM wcsdbuser.geonode  WHERE geonode_id = 12051;    
 DO
   ECHO row.identifier;
  END FOR; 
END@



Выдает кучу ошибок, в том числе и вот такое

SQL0104N An unexpected token "FOR" was found following "END ". Expected ...

Подскажите, в каком направлении искать?
PS. PL/SQL версию от DB2 не предлагать, надо на SQL PL
...
Рейтинг: 0 / 0
10.08.2012, 10:09
    #37911718
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya Ilyinov,

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
set serveroutput on@

BEGIN ATOMIC 
   FOR  row AS
    SELECT identifier, type FROM wcsdbuser.geonode  WHERE geonode_id = 12051;
  DO
    ECHO row.identifier;
    call dbms_output.put_line(row.identifier);
  END FOR; 
END@

Не забудьте установить символ завершения команды в '@' вместо ';', который по-умолчанию.
Полезно почитать также про SQL Procedural Language (SQL PL) .
...
Рейтинг: 0 / 0
13.08.2012, 04:03
    #37913885
Kostya Ilyinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Mark Barinstein,

Спасибо - попробовал. Пока не получается. Вот моя версия - так что может дело еще в этом:
Код: plaintext
1.
2.
3.
4.
5.
6.
D:\work>db2level
DB21085I  Instance "DB2" uses "32" bits and DB2 code release "SQL09057" with
level identifier "06080107".
Informational tokens are "DB2 v9.5.700.579", "s101129", "IP23137", and Fix Pack

"7".
Product is installed at "D:\IBM\SQLLIB" with DB2 Copy Name "DB2COPY1".

Выхлоп ниже:

Код: 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.
D:\work>db2 < test.sql
(c) Copyright IBM Corporation 1993,2007
Command Line Processor for DB2 Client 9.5.7

You can issue database manager commands and SQL statements from the command
prompt. For example:
    db2 => connect to sample
    db2 => bind sample.bnd

For general help, type: ?.
For command help, type: ? command, where command can be
the first few keywords of a database manager command. For example:
 ? CATALOG DATABASE for help on the CATALOG DATABASE command
 ? CATALOG          for help on all of the CATALOG commands.

To exit db2 interactive mode, type QUIT at the command prompt. Outside
interactive mode, all commands must be prefixed with 'db2'.
To list the current command option settings, type LIST COMMAND OPTIONS.

For more detailed help, refer to the Online Reference Manual.

db2 => DB21034E  The command was processed as an SQL statement because it was no
t a
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "on@" was found following "set serveroutput ".
Expected tokens may include:  "=".  SQLSTATE=42601
db2 => db2 => 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 "BEGIN
ATOMIC  ".  Expected tokens may include:  "END".  LINE NUMBER=1.
SQLSTATE=42601
db2 => DB21034E  The command was processed as an SQL statement because it was no
t a
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "row" was found following "FOR ".  Expected
tokens may include:  "JOIN <joined_table>".  SQLSTATE=42601
db2 =>
IDENTIFIER                                                       TYPE
---------------------------------------------------------------- ----
Canada                                                           CNTY
United States                                                    CNTY
Australia                                                        CNTY

  3 record(s) selected.

db2 => DB21034E  The command was processed as an SQL statement because it was no
t a
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "END-OF-STATEMENT" was found following "DO".
Expected tokens may include:  "JOIN <joined_table>".  SQLSTATE=42601
db2 => SQL0206N  "ROW.IDENTIFIER" is not valid in the context where it is used.

SQLSTATE=42703
db2 => DB21034E  The command was processed as an SQL statement because it was no
t a
valid Command Line Processor command.  During SQL processing it returned:
SQL0104N  An unexpected token "FOR" was found following "END ".  Expected
tokens may include:  "JOIN <joined_table>".  SQLSTATE=42601
db2 => DB21034E  The command was processed as an SQL statement because it was no
t 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
db2 =>

Не похоже на то, что ему нравится даже самое начало. Пробовал

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
set serveroutput on@

BEGIN ATOMIC 
  FOR row AS
    SELECT identifier, type FROM wcsdbuser.geonode where type = 'CNTY'
  DO
    call dbms_output.put_line(row.identifier);
  END FOR; 
END@



Запускаю так:
Код: plaintext
db2 < test.sql

Также пробовал
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
set serveroutput=on@

BEGIN ATOMIC 
  FOR row AS
    SELECT identifier, type FROM wcsdbuser.geonode where type = 'CNTY'
  DO
    call dbms_output.put_line(row.identifier);
  END FOR; 
END@



Теперь ругается на SERVEROUTPUT:

Код: plaintext
1.
2.
3.
4.
db2 => DB21034E  The command was processed as an SQL statement because it was no
t a
valid Command Line Processor command.  During SQL processing it returned:
SQL0206N  "SERVEROUTPUT" is not valid in the context where it is used.
SQLSTATE=42703

ну и дальше прежние ошибки.

Марк, спасибо - почитал про мою версию SQL PL, вроде все должно работать. Я правильно понимаю, что эта структура называется Inline Compound Statement? Может есть какие-то ограничения по использованию циклов? Но я ведь видел пример, собственно из которого и делал свой блок:

Код: plsql
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.
CREATE TABLE TARGET
     (PK INTEGER NOT NULL
     PRIMARY KEY, C1 INTEGER);
CREATE TABLE EXCEPT
     (PK INTEGER NOT NULL
     PRIMARY KEY, C1 INTEGER);
CREATE TABLE SOURCE
     (PK INTEGER NOT NULL
     PRIMARY KEY, C1 INTEGER);
CREATE FUNCTION DISCRETIZE(RAW INTEGER) RETURNS INTEGER
     RETURN CASE
       WHEN RAW < 0 THEN CAST(NULL AS INTEGER)
       WHEN RAW > 1000 THEN NULL
       ELSE ((RAW / 10) * 10) + 5
     END;
INSERT INTO SOURCE (PK, C1) 
     VALUES (1,   -5),
            (2, NULL),
            (3, 1200),
            (4,   23),
            (5,   10),
            (6,  876);
     BEGIN ATOMIC
       FOR ROW AS
         SELECT PK, C1, DISCRETIZE(C1) AS D FROM SOURCE
       DO
         IF ROW.D IS NULL THEN
           INSERT INTO EXCEPT VALUES(ROW.PK, ROW.C1);
         ELSE
           INSERT INTO TARGET VALUES(ROW.PK, ROW.D);
         END IF;
       END FOR;
     END



http://pic.dhe.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=/com.ibm.db2.luw.sql.ref.doc/doc/r0004240.html?Open

Там опять же 9.7, но по идее должно работать и в 9.5? Прошу прощения у профессионалов за такой дилетантский вопрос, просто уже нет мочи переводить простыни кодов ошибок.
...
Рейтинг: 0 / 0
13.08.2012, 11:14
    #37914110
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya Ilyinov,

Не надо использовать файл с командами в таком виде:
db2 < test.sql
В 9.5 нет команды set serveroutput, модуля dbms_output, compiled compound запросов.
Там есть Compound SQL (Dynamic) statement .
Когда вы используете эти запросы, вы должны изменить символ разделитель запросов.
Т.е. вместо
db2 -tf test.sql
где по-умолчанию используется символ-разделитель команд ';', можно использовать символ '@', например:
db2 -td@ -f test.sql
test.sql
Код: 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.
CREATE TABLE TARGET
     (PK INTEGER NOT NULL
     PRIMARY KEY, C1 INTEGER)@

CREATE TABLE EXCEPT
     (PK INTEGER NOT NULL
     PRIMARY KEY, C1 INTEGER)@

CREATE TABLE SOURCE
     (PK INTEGER NOT NULL
     PRIMARY KEY, C1 INTEGER)@

CREATE FUNCTION DISCRETIZE(RAW INTEGER) RETURNS INTEGER
     RETURN CASE
       WHEN RAW < 0 THEN CAST(NULL AS INTEGER)
       WHEN RAW > 1000 THEN NULL
       ELSE ((RAW / 10) * 10) + 5
     END@

INSERT INTO SOURCE (PK, C1) 
     VALUES (1,   -5),
            (2, NULL),
            (3, 1200),
            (4,   23),
            (5,   10),
            (6,  876)@

     BEGIN ATOMIC
       FOR ROW AS
         SELECT PK, C1, DISCRETIZE(C1) AS D FROM SOURCE
       DO
         IF ROW.D IS NULL THEN
           INSERT INTO EXCEPT VALUES(ROW.PK, ROW.C1);
         ELSE
           INSERT INTO TARGET VALUES(ROW.PK, ROW.D);
         END IF;
       END FOR;
     END@
А вообще, не используйте compound запросы без надобности.
В вашем случае вместо этого compound с циклом можно было бы:
Код: plaintext
1.
2.
INSERT INTO EXCEPT
SELECT PK, COALESCE(DISCRETIZE(C1), C1) 
FROM SOURCE
...
Рейтинг: 0 / 0
13.08.2012, 11:47
    #37914200
Kostya Ilyinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Mark Barinstein,

Спасибо за ответ - завтра буду пробовать снова. Приведенный код (работающий) - это пример, мне же нужно циклом пробежаться по массиву строк и вставить данные в 2-3 таблицы. Можно конечно сначала это все вставить во временную таблицу наверно, но этот подход мне видится костыльным.
...
Рейтинг: 0 / 0
13.08.2012, 17:02
    #37914882
A.Panskikh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya Ilyinov
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
       FOR ROW AS
         SELECT PK, C1, DISCRETIZE(C1) AS D FROM SOURCE
       DO
         IF ROW.D IS NULL THEN
           INSERT INTO EXCEPT VALUES(ROW.PK, ROW.C1);
         ELSE
           INSERT INTO TARGET VALUES(ROW.PK, ROW.D);
         END IF;
       END FOR;
     END





А точно нужно использовать подобные конструкции? Не достаточно ли

Код: sql
1.
2.
           INSERT INTO EXCEPT   SELECT PK, C1 FROM SOURCE where DISCRETIZE(C1) is null;
           INSERT INTO TARGET   SELECT PK, DISCRETIZE(C1) D FROM SOURCE where DISCRETIZE(C1) is not null;





Andy
...
Рейтинг: 0 / 0
13.08.2012, 18:58
    #37915048
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya IlyinovПриведенный код (работающий) - это пример, мне же нужно циклом пробежаться по массиву строк и вставить данные в 2-3 таблицы. Можно конечно сначала это все вставить во временную таблицу наверно, но этот подход мне видится костыльным.Это только на тестах можно определить, как оно быстрее будет.
Обычно групповая обработка записей идёт быстрее обработки в цикле, но бывают исключения.
Можно и одной командой в несколько таблиц изменения делать без временных таблиц.
...
Рейтинг: 0 / 0
14.08.2012, 03:23
    #37915333
Kostya Ilyinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Mark Barinstein,

Можно наверняка. Но мне хочется избежать дублирования данных. Я хочу определить массив с именами штатов/страной, и массив с типом объекта (штат/страна). И в цикле пробежаться по массиву (любому, они имеют одинаковую длину по определению) и вставить строки в соотв. таблицы. Как такое сделать не прибегая к какому-либо хранилищу, будь то массив или таблица, и не дублируя значения в операциях вставки, я пока не представляю.
...
Рейтинг: 0 / 0
14.08.2012, 03:25
    #37915334
Kostya Ilyinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
A.Panskikh,

Коллеги, я наверно сбил вас с толку публикацией примера с
Код: plsql
1.
 SELECT PK, C1, DISCRETIZE(C1) AS D FROM SOURCE

. Я лишь демонстрировал что я пробовал, и как оно схоже по конструкции с моей задачей.
...
Рейтинг: 0 / 0
14.08.2012, 10:43
    #37915524
A.Panskikh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya IlyinovЯ лишь демонстрировал что я пробовал, и как оно схоже по конструкции с моей задачей.

Собственно и я о том же. Мы работаем с базой и нужно перестроить мозг на решение задач иными, непрограммистскими, методами. Много хороших примеров можно почерпнуть из DB2 SQL Cookbook.

Andy
...
Рейтинг: 0 / 0
14.08.2012, 10:47
    #37915530
Mark Barinstein
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya IlyinovНо мне хочется избежать дублирования данных. Я хочу определить массив с именами штатов/страной, и массив с типом объекта (штат/страна). И в цикле пробежаться по массиву (любому, они имеют одинаковую длину по определению) и вставить строки в соотв. таблицы. Как такое сделать не прибегая к какому-либо хранилищу, будь то массив или таблица, и не дублируя значения в операциях вставки, я пока не представляю.Только сейчас заметил, что мой пример неправильный был - вы вставляете в 2 разные таблицы по условию.
Но смысл остаётся тот же, так рекомендуют во многих СУБД делать - если можно обойтись без процедурного языка, то как правило, лучше обойтись чистым SQL.
В данном случае не надо бояться сделать 2 insert select из одной и той же таблицы, но с разными условиями - как правило массовая вставка будет идти быстрее, чем одиночные вставки, хотя и базовая таблица будет сканироваться 2-жды.
На небольшом количестве записей это всё равно, но на значительных объёмах данных вы, скорее всего, увидите разницу.
...
Рейтинг: 0 / 0
14.08.2012, 11:01
    #37915557
Kostya Ilyinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Mark Barinstein,

Спасибо, буду делать через промежуточную таблицу. Немного оффтопика: а есть ли тут полиглоты DB2/Oracle - мне одному кажется, что в Oracle PL/SQL все это гораздо проще? Не пойму, то ли привык к документации оракловской с детальными описаниями и примерами, то ли концептуально языки так отличаются?
...
Рейтинг: 0 / 0
14.08.2012, 15:12
    #37916057
Andron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya IlyinovMark Barinstein,

Спасибо, буду делать через промежуточную таблицу. Немного оффтопика: а есть ли тут полиглоты DB2/Oracle - мне одному кажется, что в Oracle PL/SQL все это гораздо проще? Не пойму, то ли привык к документации оракловской с детальными описаниями и примерами, то ли концептуально языки так отличаются?

На мой взгляд процедурные языки у db2 и oracle по легкости освоения примерно одинаковы.
...
Рейтинг: 0 / 0
14.08.2012, 17:06
    #37916361
A.Panskikh
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
Kostya Ilyinov полиглоты DB2/Oracle - [...] концептуально языки так отличаются?

Есть у IBM Oracle to DB2 Conversion Guide: Compatibility Made Easy (redbook, SG24-7736) - должен помочь в переходе между системами. Где-то мне попадался гайд с названием типа DB2 for Oracle DBA, можно погуглить.

Andy
...
Рейтинг: 0 / 0
14.08.2012, 17:54
    #37916465
Kostya Ilyinov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DB2 CLP и SQL PL
A.Panskikh,

Спасибо, почитаю. Утром буду решать задачу через универсальный интерфейс промежуточную таблицу.
...
Рейтинг: 0 / 0
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / DB2 CLP и SQL PL / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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