SQL скрипт (FireBird)

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

SQL скрипт (FireBird)

Сообщение BasiL » 25 янв 2005, 15:27

Здравствуйте!
Можно ли написать на сабже такой скрипт, который при проливки его смотрел существует ли база, таблица, хранимая процедура и т.д. и например при условии, что таблица не существует он бы создал ее или хранимую процедуру?
Или для этих условий придется использовать рукописную UDF библиотеку?

Например кусок MsSQL скрипта

Код: Выделить всё

if exists (select * from sysobjects where id = object_id('MyTable'))
  drop table MyTable
go

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: SQL скрипт (FireBird)

Сообщение Merlin » 25 янв 2005, 16:31

BasiL писал(а):Здравствуйте!
Можно ли написать на сабже такой скрипт, который при проливки его смотрел существует ли база, таблица, хранимая процедура и т.д. и например при условии, что таблица не существует он бы создал ее или хранимую процедуру?
Или для этих условий придется использовать рукописную UDF библиотеку?

Например кусок MsSQL скрипта

Код: Выделить всё

if exists (select * from sysobjects where id = object_id('MyTable'))
  drop table MyTable
go
Начни с чтения оглавления LangRef.pdf

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 25 янв 2005, 16:32

тебе для сравнения структуры баз? тогда это IBComparer. См. IBExpert и т.п.

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 25 янв 2005, 17:09

2Kdv
Мне надо написать именно скрипт, который при запуске с нуля создавал БД, в ней таблицы тригеры и процедуры. Но у меня сейчас загвоздка в том, как сделать, что бы при проливки второй раз этого скрипта БД и таблицы не трогались (или дополнялись записями, которых нет в БД), а процедуры перепроливались.

ЗЫ Надо что бы этот скрипт проливался без помощи каких либо других программ, а с помощью isql.exe

2Merlin
Ты можешь дать указатель на конкректную страницу?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 25 янв 2005, 17:41

насчет langref - а не ломотно тебе будет на www.ibase.ru навести мышь на Firebird и потом "документация"?

насчет isql - НЕТ, он не дает такой возможности. попробуй IBEScript (ibexpert.com).
И все таки, раз НЕ надо создавать таблицы, которые есть, речь идет именно о накате изменений на оригинальную БД. То есть, у тебя есть ориг. БД, ты ее копию меняешь, потом напускаешь IBComparer и он тебе выдает СКРИПТ ДЛЯ ISQL, которым оригинальная база приводится к новому состоянию.

насчет "дополнения записей", которых нет в БД - isql не занимается извлечением ВСЕХ записей из БД. Данные он выводит только через select. поэтому тебе придется озаботиться самостоятельно синхронизацией данных. Что в общем то, через скрипт никогда не делают.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 25 янв 2005, 17:51

BasiL писал(а):2Kdv
Мне надо написать именно скрипт, который при запуске с нуля создавал БД, в ней таблицы тригеры и процедуры. Но у меня сейчас загвоздка в том, как сделать, что бы при проливки второй раз этого скрипта БД и таблицы не трогались (или дополнялись записями, которых нет в БД), а процедуры перепроливались.

ЗЫ Надо что бы этот скрипт проливался без помощи каких либо других программ, а с помощью isql.exe
Скриптер isql не имеет возможности управлять ветвлением. Но и не валится на исключениях, а продолжает выполнять последующие операторы. Так что если таблица есть, то он доложит об исключении при попытке создания и спокойненько пойдёт себе дальше. То же и с созданием полей. А процедуры можно RECREATE, можно CREATE OR ALTER. Я бы послал тебя за этим в Release Notes, но ты же номер строки потребуешь.

BasiL писал(а): 2Merlin
Ты можешь дать указатель на конкректную страницу?
Могу, но не хочу. Если тебе _для себя_ лень в поиске Акробата набрать "system tables" или просто пролистать оглавление, то мне и подавно его запускать лень.

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 26 янв 2005, 09:29

kdv писал(а):И все таки, раз НЕ надо создавать таблицы, которые есть, речь идет именно о накате изменений на оригинальную БД. То есть, у тебя есть ориг. БД, ты ее копию меняешь, потом напускаешь IBComparer и он тебе выдает СКРИПТ ДЛЯ ISQL, которым оригинальная база приводится к новому состоянию.
А потом удаленно бабушкам бухгалтерам объяснять как это сделать :D
Merlin писал(а):Я бы послал тебя за этим в Release Notes, но ты же номер строки потребуешь.
:D

Итог напрашивается сам. А не пошел бы ты на ... Interbase API

ЗЫ Я тут наваял с помощью батника такую вещь

Код: Выделить всё

if not exist data.gdb goto create_db
:run01
call isql.bat create_tables.sql
call isql.bat update_tables.sql
rem call isql.bat test.sql
goto end

:create_db
call isql.bat create_db.sql
goto run01

:end
Последний раз редактировалось BasiL 26 янв 2005, 14:39, всего редактировалось 2 раза.

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 26 янв 2005, 10:02

Помогите.
Скрипт, который в таблицу test добавляет записи, если они не существуют. Скрипт работает корректно, если в таблице test есть хоть одна запись, а если записей нет, то в нее ничего не добавляется :(

Код: Выделить всё

connect 'data.gdb';

create table temp_test (
       field1 char(3),
       field2 char(3)
);

insert into temp_test (field1, field2) values ('840','USD');
insert into temp_test (field1, field2) values ('978','EUR');

insert into test (field1, field2)
select distinct tt.field1, tt.field2
  from temp_test tt,
       test t
 where t.field1 <> tt.field1
   and t.field2 <> tt.field2;

drop table temp_test;

select * from test;
ЗЫ Если убрать distinct результат такой же.

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 26 янв 2005, 14:40

Вопрос снят, сам разобрался.

Скрипт который апдейтит таблицу.

Код: Выделить всё

connect 'data.gdb';

create table temp_test (
       field1 char(3),
       field2 char(3)
);

insert into temp_test (field1, field2) values ('840','USD');
insert into temp_test (field1, field2) values ('978','EUR');

insert into test (field1, field2)
select field1, field2
  from temp_test
 where field1 not in (select field1 from test);

drop table temp_test;

Лысый
Сообщения: 177
Зарегистрирован: 08 ноя 2004, 08:20

Сообщение Лысый » 26 янв 2005, 16:59

Это называется смешивание ddl и dml. commit-ы не забывай....

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 27 янв 2005, 11:11

Вот добрался до генераторов.

Вопрос вот какой, как лучьше сделать, если при повторной проливки скрипта, где создаются генераторы и выставляются их значения, что бы эти генераторы снова не занулялись?

Я сделал так, создал процедуры, для каждого генератора, процедура возвращает, если генератор = 0, то 1, а если все остальное, то текущее значение. Стал писать скрипт для SET GENERATOR, вот кусок

Код: Выделить всё

declare new_id numeric(15,0);
execute procedure curr_id_gen_doc returning_values new_id;
SET GENERATOR NEW_ID_GEN_DOC TO new_id;
При запуске его через isql.exe пишет
Statement failed, SQLCODE = -104

Dynamic SQL Error
-SQL error code = -104
-Token unknown - line 5, char 9
-new_id
Statement failed, SQLCODE = -104

Dynamic SQL Error
-SQL error code = -104
-Token unknown - line 1, char 35
-returning_values
Statement failed, SQLCODE = -104

Dynamic SQL Error
-SQL error code = -104
-Token unknown - line 1, char 33
-new_id
Еще вопрос, а можно в теле процедуры использовать такие команды как CREATE, SET?

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 27 янв 2005, 12:37

И еще вопрос, можно в системных таблицах обновить генератор самому через update?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 27 янв 2005, 13:58

значения генераторов не хранятся ни в каких таблицах. они хранятся на специальных страницах БД. поэтому значение генератора можно изменить либо gen_id-ом, либо set generator.

слушай, ты ведь городишь что-то такое кривое... сам говоришь, что надо бабушкам-бухгалтерам базу обновлять, и одновременно какие-то скрипты мастрячишь... И упорно не хочешь смотреть ibcomparer. правда, конечно, он только метаданные сравнивает. Данные это ты уж как-нибудь сам, хотя я смутно понимаю задачу обновления данных на удаленной машине. Если ты, конечно, не строишь таким образом репликацию.

т.е. ощущение, что ты закапываешься куда-то не туда. ](*,)

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 27 янв 2005, 14:32

kdv писал(а): т.е. ощущение, что ты закапываешься куда-то не туда. ](*,)
Причём упорно не желает читать доку судя по вопросам. Нехай сам варится имхо.

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 27 янв 2005, 15:16

Просто все дело в моем кривом языке, поэтому толком и не могу объяснить чего хочу.
kdv писал(а):слушай, ты ведь городишь что-то такое кривое... сам говоришь, что надо бабушкам-бухгалтерам базу обновлять, и одновременно какие-то скрипты мастрячишь...
Да надо, но это должно происходить без чьего либо участия. И уж темболее меня не будет рядом, что бы это самому сделать, вот и приходится делать скрипты. Так надо еще и учитывать такую возможность, что при запуске этих же скриптов базы пополнялись несуществующими данными, а такие вещи как генераторы оставались неизмененные.
Merlin писал(а):Причём упорно не желает читать доку судя по вопросам. Нехай сам варится имхо.
Доки я читаю, пишу скрипты 3-ий день, вот и прошу советов у людей, которые больше времени чем я работают с InterBase`ом. Всегда есть обходные пути, а их как правило недокументируют.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Сообщение Merlin » 27 янв 2005, 16:22

BasiL писал(а):Просто все дело в моем кривом языке, поэтому толком и не могу объяснить чего хочу.
kdv писал(а):слушай, ты ведь городишь что-то такое кривое... сам говоришь, что надо бабушкам-бухгалтерам базу обновлять, и одновременно какие-то скрипты мастрячишь...
Да надо, но это должно происходить без чьего либо участия. И уж темболее меня не будет рядом, что бы это самому сделать, вот и приходится делать скрипты. Так надо еще и учитывать такую возможность, что при запуске этих же скриптов базы пополнялись несуществующими данными, а такие вещи как генераторы оставались неизмененные.
Голубчик, ты явно изобретаешь лисапет, причём не на круглых колёсах. Прямо здесь есть отдельный форум, который называется Репликация, так тебе туда. А ещё на этом сайте есть раздел статей по репликации. Помогать тебе решать частные проблемы количества углов на колёсах бессмыссленно, ты ознакомься с проблемой и зарытыми в ней граблями в целом, по опыту уже понаступавших, глядишь и вопросы другие пойдут.

BasiL
Сообщения: 9
Зарегистрирован: 25 янв 2005, 15:16

Сообщение BasiL » 27 янв 2005, 17:52

Пусть я изобретаю велосипед с квадратными колесами. Мня репликация на данный момент мало интересует. Сейчас меня больше интересует автоматическое пополнение базы по мере ее надобности, без участия юзера, с помощью скриптов, которые играют две роли:
1. Если базы нет, то создать полную базу.
2. Если база есть, то пополнить ее тем, чего в ней нет.

А это грабли для тех кто с зади.
Решение с генераторами такое, создаю генераторы без присвоения им начального значения, при создании они устонавливаются в "0", а при повторной проливки скриптов, ругается, что генератор создан, но его значение не обнуляется.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 27 янв 2005, 18:07

это тоже обсуждалось и в epsylon.public.interbase. я так понял, что тебя чужой опыт или варианты решений не интересуют.
1. Если базы нет, то создать полную базу.


зачем ее "создавать" если ее можно ДАТЬ. в виде готового gdb.
2. Если база есть, то пополнить ее тем, чего в ней нет.
разница в метаданных решается IBComparer-ом.
А вот что уже ты понимаешь под "пополнить ее тем, чего в ней нет", я не знаю, но только скриптами это пытаться делать бессмыслено. Это должна делать программа, возможно отдельная, которая должна соображать где чего нет, и чего куда в каком виде залить. То есть, фактически, нечто вроде оффлайнового репликатора.

Ответить