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

Откуда: СПБ
Сообщений: 34
Подскажите пжалста, как корректно составить запрос. Нужно дропнуть таблицу в случае, если она создана.

Вот такой вот запрос выдает
Function sequence error =(

IF ( EXISTS (SELECT * FROM SYSCAT.TABLES WHERE TABSCHEMA = 'FK_02' AND TABNAME = 'T_DT';) )
DROP TABLE FK_02.T_DT;
END IF;
30 июн 05, 10:56    [1661943]     Ответить | Цитировать Сообщить модератору
 Re: Аналог доки Concepts по Oracle для DB2  [new]
Victor Metelitsa
Member

Откуда: Тюмень
Сообщений: 2550
Во-первых, лишний semicolon после TABNAME = 'T_DT'.

Во-вторых, EXISTS в IF'е, насколько я помню, не работает, и надо использовать что-то вроде
DECLARE tn VARCHAR(255);
SET tn=(SELECT tabName 
  FROM SYSCAT.TABLES 
  WHERE TABSCHEMA = 'FK_02' AND TABNAME = 'T_DT'
  FETCH 1 FIRST ROW ONLY);
IF NOT(tn IS NULL) THEN
  DROP TABLE FK_02.T_DT;
END IF;
Есть еще вариант с попыткой сделать SELECT из FK_02.T_DT с последующим перехватом исключения, но он, на мой взгляд, менее удобен.

В-третьих, все равно это работать не должно (
All executable SQL statements can be contained within the body of an SQL procedure, with the exception of the following:
ALTER
CONNECT
CREATE any object other than indexes, tables, or views
DESCRIBE
DISCONNECT
DROP any object other than indexes, tables, or views
FLUSH EVENT MONITOR
REFRESH TABLE
RELEASE (connection only)
RENAME TABLE
RENAME TABLESPACE
REVOKE
SET CONNECTION
SET INTEGRITY
SET PASSTHRU
SET SERVER OPTION
).

Хотя стоит попробовать
DECLARE tn VARCHAR(255);
SET tn=(SELECT tabName 
  FROM SYSCAT.TABLES 
  WHERE TABSCHEMA = 'FK_02' AND TABNAME = 'T_DT'
  FETCH 1 FIRST ROW ONLY);
IF NOT(tn IS NULL) THEN
  EXECUTE IMMEDIATE 'DROP TABLE FK_02.T_DT';
END IF;
30 июн 05, 11:48    [1662219]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
massaraksh33
Member

Откуда: СПБ
Сообщений: 34
Да, к сожалению, ничего не работает.
Спасибо, Victor.
30 июн 05, 16:01    [1663818]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
Victor Metelitsa
Member

Откуда: Тюмень
Сообщений: 2550
вот это компилится:
create procedure XXX
begin atomic
DECLARE i INTEGER;
DECLARE s VARCHAR(255);

SET i=(SELECT 1
  FROM SYSCAT.TABLES 
  WHERE TABSCHEMA = 'FK_02' AND TABNAME = 'T_DT'
  FETCH FIRST 1 ROW ONLY);
IF i=1 THEN
  SET s = 'DROP TABLE FK_02.T_DT';
  EXECUTE IMMEDIATE s;
END IF;
end
причем по сравнению с предыдущим
1. create procedure - обязательно.
2. FETCH FIRST 1 ROW ONLY вместо FETCH 1 FIRST ROW ONLY
3. SET s = 'DROP TABLE FK_02.T_DT';
EXECUTE IMMEDIATE s;
вместо
EXECUTE IMMEDIATE 'DROP TABLE FK_02.T_DT';

а SELECT 1 "для красоты"
1 июл 05, 14:04    [1667318]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
massaraksh33
Member

Откуда: СПБ
Сообщений: 34
Victor Metelitsa
вот это компилится:
create procedure XXX
begin atomic
DECLARE i INTEGER;
DECLARE s VARCHAR(255);

SET i=(SELECT 1
  FROM SYSCAT.TABLES 
  WHERE TABSCHEMA = 'FK_02' AND TABNAME = 'T_DT'
  FETCH FIRST 1 ROW ONLY);
IF i=1 THEN
  SET s = 'DROP TABLE FK_02.T_DT';
  EXECUTE IMMEDIATE s;
END IF;
end
причем по сравнению с предыдущим
1. create procedure - обязательно.
2. FETCH FIRST 1 ROW ONLY вместо FETCH 1 FIRST ROW ONLY
3. SET s = 'DROP TABLE FK_02.T_DT';
EXECUTE IMMEDIATE s;
вместо
EXECUTE IMMEDIATE 'DROP TABLE FK_02.T_DT';

а SELECT 1 "для красоты"


Вах! Спасибо! Однако как сложно все...
1 июл 05, 18:11    [1668806]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
Victor Metelitsa
Member

Откуда: Тюмень
Сообщений: 2550
Вопрос привычки. В том числе - привычки регулярно перечитывать доки. К примеру, мне совершенно непонятно, почему у DB2 нелегально

EXECUTE IMMEDIATE 'DROP TABLE FK_02.T_DT';

и легально

SET s = 'DROP TABLE FK_02.T_DT';
EXECUTE IMMEDIATE s;

однако о необходимости этого после перечитывания статьи по EXECUTE IMMEDIATE догадаться можно.

А ораклисты вместо exists в if'ах вообще часто польуются обработкой исключений, что, на мой взгляд, еще более громоздко в данном применении.
1 июл 05, 20:15    [1669075]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
Victor Metelitsa
Member

Откуда: Тюмень
Сообщений: 2550
Кстати, пример из документации ;-)
CREATE PROCEDURE EXIT_TEST ()
LANGUAGE SQL
BEGIN
  DECLARE OUT_BUFFER VARCHAR(80);
  DECLARE NO_TABLE CONDITION FOR SQLSTATE ‘42704’;
  A: 
    BEGIN
      DECLARE EXIT HANDLER FOR NO_TABLE 
        BEGIN 
          SET OUT_BUFFER=‘Table does not exist’;  
        END;
      -- Drop potentially nonexistent table:
      DROP TABLE JAVELIN;
      B: SET OUT_BUFFER=‘Table dropped successfully’;
    END;
  -- Copy OUT_BUFFER to some message table:
  C: INSERT INTO MESSAGES VALUES OUT_BUFFER;
END
3 июл 05, 11:28    [1670266]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
massaraksh33
Member

Откуда: СПБ
Сообщений: 34
Еще раз большое спасибо! Надо, конечно, читать документацию... Только времени нет =(
4 июл 05, 11:39    [1671383]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
ggv
Member

Откуда:
Сообщений: 1810
появилась системная SP которая позволяет вызвать функционал CLP из SQL
Тоже вариант, просто и удобно.
4 июл 05, 11:40    [1671388]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
TORT
Member

Откуда:
Сообщений: 1095
А как проца называеЦЦа???
4 июл 05, 11:53    [1671466]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
ggv
Member

Откуда:
Сообщений: 1810
http://publib.boulder.ibm.com/infocenter/db2help/topic/com.ibm.db2.udb.doc/admin/r0012547.htm
умеет не так много пока, но ведь это только начало - она появилась только в FixPack 9
подписывайтесь на бесплатную доставку DB2 magazine и читайте, хороший журнал. Наш журнал.
4 июл 05, 12:17    [1671601]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
ggv
Member

Откуда:
Сообщений: 1810
ну и вот еще, что новенького -
http://www-128.ibm.com/developerworks/db2/library/techarticle/dm-0506zikopoulos/index.html
4 июл 05, 15:55    [1672740]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
Leha123
Member

Откуда: Eburg
Сообщений: 36
ggv, свяжись плиз со мной...
аська 230281

или мылом piffi(dog)bk(dot)ru
6 июл 05, 20:06    [1682060]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
Leha123
Member

Откуда: Eburg
Сообщений: 36
Leha123
ggv, свяжись плиз со мной...
аська 230281

или мылом piffi(dog)bk(dot)ru
paffi(dog)bk(dot)ru
6 июл 05, 20:07    [1682062]     Ответить | Цитировать Сообщить модератору
 Re: запрос - создан ли объект  [new]
massaraksh33
Member

Откуда: СПБ
Сообщений: 34
Хммм... вернемся к теме. Вот чего в итоге получилось. Может пригодится кому... Можно и через case - будет быстрее, но тогда с одним вариантом определения на тип объекта.




CREATE PROCEDURE DROPPER (IN obj_type VARCHAR(255), IN obj_schema VARCHAR(255), IN obj_name VARCHAR(255))
/*
* Drops schema object by its type.
* If object is not exists, error is not raised.
*/
BEGIN ATOMIC
DECLARE i INTEGER;
DECLARE o_type VARCHAR(255);
DECLARE s VARCHAR(255);

SET o_type = LTRIM(RTRIM(LCASE(obj_type)));

IF o_type IN ('t', 'tab', 'table', 'q', 'que', 'query', 'query table')
THEN BEGIN
SET o_type = ' TABLE ';
SET i=(SELECT 1
FROM SYSCAT.TABLES
WHERE TABSCHEMA = obj_schema AND TABNAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('v', 'vie', 'view')
THEN BEGIN
SET o_type = ' VIEW ';
SET i=(SELECT 1
FROM SYSCAT.VIEWS
WHERE VIEWSCHEMA = obj_schema AND VIEWNAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('a', 'ali', 'alias')
THEN BEGIN
SET o_type = ' ALIAS ';
SET i=(SELECT 1
FROM SYSCAT.TABLES
WHERE TABSCHEMA = obj_schema AND TABNAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('f', 'fn', 'fun', 'func', 'function')
THEN BEGIN
SET o_type = ' FUNCTION ';
SET i=(SELECT 1
FROM SYSCAT.ROUTINES
WHERE ROUTINESCHEMA = obj_schema AND ROUTINENAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('p', 'pro', 'proc', 'procedure')
THEN BEGIN
SET o_type = ' PROCEDURE ';
SET i=(SELECT 1
FROM SYSCAT.ROUTINES
WHERE ROUTINESCHEMA = obj_schema AND ROUTINENAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('i', 'ind', 'idx', 'index')
THEN BEGIN
SET o_type = ' INDEX ';
SET i=(SELECT 1
FROM SYSCAT.INDEXES
WHERE INDSCHEMA = obj_schema AND INDNAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('tr', 'tri', 'trig', 'trigger')
THEN BEGIN
SET o_type = ' TRIGGER ';
SET i=(SELECT 1
FROM SYSCAT.TRIGGERS
WHERE TRIGSCHEMA = obj_schema AND TRIGNAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('typ', 'type', 'datatype')
THEN BEGIN
SET o_type = ' DISTINCT TYPE ';
SET i=(SELECT 1
FROM SYSCAT.DATATYPES
WHERE TYPESCHEMA = obj_schema AND TYPENAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSEIF o_type IN ('s', 'seq', 'sequence')
THEN BEGIN
SET o_type = ' SEQUENCE ';
SET i=(SELECT 1
FROM SYSCAT.SEQUENCES
WHERE SEQSCHEMA = obj_schema AND SEQNAME = obj_name
FETCH FIRST 1 ROW ONLY);
END;
ELSE
BEGIN
END;
END IF;

IF i=1 THEN
SET s = 'DROP ' || o_type || obj_schema || '.' || obj_name;
EXECUTE IMMEDIATE s;
END IF;
END;
8 июл 05, 10:24    [1686821]     Ответить | Цитировать Сообщить модератору
Все форумы / IBM DB2, WebSphere, IMS, U2, etc Ответить