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

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

Возникла необходимость в написании простого запроса для проверки наличия поля в таблице и создания при необходимости.
Но вот никак не могу сообразить, перепробовал множество вариантов. Знаю, что с процедурами все работает, но мне нужно вне процедуры. Суть задачи: есть программа-генератор скриптов по обновлению БД. БД внешняя, в ней нельзя создавать свои процедурки.

С db2 работаю аж 3 дня, простите если вопрос тривиальный.
Вот запросы, которые я пробовал.

BEGIN ATOMIC
IF (NOT EXISTS(
SELECT 1 FROM SYSCAT.COLUMNS WHERE TABNAME ='TEST_TABLE' AND COLNAME = 'TEST2'))
THEN
EXECUTE IMMEDIATE 'alter table ... add ...'!
END IF!
END
GO
--#SET DELIMITER ;


====================

BEGIN ATOMIC
IF (NOT EXISTS(
SELECT 1 FROM SYSCAT.COLUMNS WHERE TABNAME ='TEST_TABLE' AND COLNAME = 'TEST2'))
THEN
alter table ... add ... ;
END IF;
END
GO
========================================
IF
(
NOT EXISTS
(
SELECT 1
FROM SYSCAT.COLUMNS
WHERE
TABSCHEMA = 'TMRO'
AND TABNAME ='test_table'
AND COLNAME = 'test_column'
)
)
THEN
alter table ... add ... ;
END IF;
5 авг 15, 13:19    [17978387]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
FYI
Guest
slitvin,

If the ATOMIC keyword is specified in a dynamically prepared compound statement or an SQL function that is not within a module, the
compound statement is processed as a compound SQL (inlined) statement.

&

EXECUTE IMMEDIATE statement
...
Invocation
This statement can only be embedded in an application program. It is an executable statement that cannot be dynamically prepared
5 авг 15, 14:57    [17978897]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4754
slitvin,

Добрый день.

+ myscript.sql
--#SET TERMINATOR @
BEGIN 
  --EXECUTE IMMEDIATE 'create table TEST_TABLE (TEST1 INT) IN USERSPACE1';
IF (NOT EXISTS(
  SELECT 1 FROM SYSCAT.COLUMNS 
  WHERE TABSCHEMA=USER AND TABNAME ='TEST_TABLE' AND COLNAME = 'TEST2'
))
THEN
  EXECUTE IMMEDIATE 'alter table TEST_TABLE add TEST2 INT';
END IF;
END
@

db2 connect to mydb ...
db2 -vf myscript.sql -z myscript.log
5 авг 15, 15:00    [17978916]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
slitvin
Member

Откуда:
Сообщений: 6
К сожалению, не работает

К сообщению приложен файл. Размер - 52Kb
5 авг 15, 17:15    [17979945]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
CawaSPb
Member

Откуда: Питер/Москва/Wroclaw
Сообщений: 973
slitvin,

А вот я бы _крайне_ не рекоменовал создавать инструменты для "условного" накатывания скриптов.

Если разработчики, формирующие поставку, не знают доподлинно, есть такое поле в БД или нет, значит у них нет контроля за состоянием структуры БД, и они вообще не знают, "на что" накатывают скрипты.

Состояние БД после такого наката будет полностью неопределено, а, например, тестирование на ней не будет иметь никакой ценности.

Инструменты для условного наката будут только маскировать ошибки. Лучше пусть скрипт свалится, чем молча накатится неправильная поставка.


PS Правды ради, успешность наката сама по себе тоже не гарантирует, что была соблюдена правильная очерёдность и полнота поставок, но зачем же усугублять возможные проблемы.

Условные накаты DDL - это костыль (вредный, но неизбежный) для СУБД, у которых DDL выполняется вне общего транзакционного механизма (и не откатывается по ошибке rollback'ом).
5 авг 15, 17:24    [17980001]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
slitvin
Member

Откуда:
Сообщений: 6
Доля правды в Ваших словах есть, однако решение выбираю не я.
Это необходимо для нескольких СУБД, но вот с db2 уже третий день бьюсь ))
5 авг 15, 17:35    [17980064]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
CawaSPb
Member

Откуда: Питер/Москва/Wroclaw
Сообщений: 973
slitvin,

Вероятней всего ошибка в том, как процессит команду сам RazorSQL.
Выполните скрипт Command Line Processor'ом командами, указанными Марком.
5 авг 15, 17:44    [17980112]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4754
slitvin,

постарайтесь в этом RazorSQL в настройках найти, как изменить statement termination character (как-то так должно быть) с ; по-умолчанию на @.
5 авг 15, 18:19    [17980293]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
slitvin
Member

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

Думаю, проблема не в termination character. Поскольку я добился выполнения скрипта ниже без его изменения

BEGIN ATOMIC
DECLARE STMT VARCHAR(200);
IF
(
NOT EXISTS
(
SELECT 1 FROM SYSCAT.COLUMNS
WHERE TABSCHEMA='DB2ADMIN' AND TABNAME ='TABLE1' AND COLNAME = 'clm1'
)
)
THEN
--alter table TABLE1 add column clm1 varchar(20);-
select * from SYSCAT.COLUMNS ;
select * from SYSCAT.COLUMNS ;
END IF;

END
5 авг 15, 18:27    [17980330]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
slitvin
Member

Откуда:
Сообщений: 6
Но вот этот брыкается на PREP S1 FROM STMT;

BEGIN ATOMIC
DECLARE STMT VARCHAR(200);
IF
(
NOT EXISTS
(
SELECT 1 FROM SYSCAT.COLUMNS
WHERE TABSCHEMA='DB2ADMIN' AND TABNAME ='TABLE1' AND COLNAME = 'clm1'
)
)
THEN
--alter table TABLE1 add column clm1 varchar(20);-
--select * from SYSCAT.COLUMNS ;
--select * from SYSCAT.COLUMNS ;
SET STMT = 'select * from SYSCAT.COLUMNS';
PREP S1 FROM STMT;
-- EXECUTE S1;
END IF;

END
5 авг 15, 18:27    [17980334]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
Mark Barinstein
Member

Откуда: Москва
Сообщений: 4754
slitvin,

В ATOMIC блоке нельзя делать PREPARE или EXECUTE.

Если этот RazorSQL не умеет выполнять
BEGIN
...
END@

а может только

BEGIN ATOMIC
...
END@

то это именно его проблемы, а не db2.
5 авг 15, 18:44    [17980408]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
slitvin
Member

Откуда:
Сообщений: 6
После долгих часов борьбы решение найдено. Слава Богу!

BEGIN NOT ATOMIC
IF
(
NOT EXISTS
(
SELECT 1 FROM SYSCAT.COLUMNS
WHERE TABSCHEMA='DB2ADMIN' AND TABNAME ='TABLE1' AND COLNAME = 'CLM1'
)
)
THEN
EXECUTE IMMEDIATE 'alter table table1 add column clm1 int';
END IF;

END
5 авг 15, 19:18    [17980534]     Ответить | Цитировать Сообщить модератору
 Re: Простой запрос без процедуры if/then/else  [new]
FYI
Guest
slitvin,

)))
Это то , что Марк и предлагал.
BEGIN NOT ATOMIC ... END = BEGIN ... END
6 авг 15, 08:39    [17981783]     Ответить | Цитировать Сообщить модератору
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Ответить