Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» InterBase и FireBird: вопросы по работе и их решение

Автор: OXDBA
Дата сообщения: 23.10.2012 15:14

Цитата:
как проверить целостность бэкапа,

Контрольным рестором.
AlexPetrovich

Цитата:
Нужен еще больший запас надежности - репликация( через определенный интервал вреени или сразу после изенения данных).

Если БД изначально проектировалась под репликацию, то да.
Автор: miwa
Дата сообщения: 25.11.2012 16:50
exteris

Цитата:
Я больше скажу, не то что подешевле, а вообще альтернативы не нашел.

Ну почему же. Альтернатива подешевле - nagios/zabbix/whatever с пачкой самописных скриптов. Правда, для этого надо очень хорошо понимать внутреннюю кухню ФБ, чтобы знать что проверять и вовремя генерировать правильные алерты. А если таких знаний нет, тогда, как по мне, два варианта - либо база некритичная и мониторить ее особо незачем (хотя для общего развития и полезно), либо база критичная и в случае проблем $200 будут каплей в море - и тогда покупается мониторилка.
Автор: victor_r
Дата сообщения: 12.12.2012 11:15
Вопрос по FB 2.5 superserver. Выполняю скрипт который бежит по ряду архивных баз и изменяет структуру базы. Из-за ряда причин (выключился свет на клиенте) в одних базах скрипт выполнился успешно, а в других нет. Как мне продолжить выполняться скрипт в нужном мне месте если я заранее не знаю где модификация прошла успешно, а где нет? Ведь отлова ошибок из скрипта нет и не предвидится.

Код:
execute block
returns(
city varchar(20),
a_path varchar(512),
a_serv varchar(512)
)
as
declare a_per int;
declare auser varchar(35);
declare apass varchar(35);
declare SQL_1 varchar(8196);
declare SQL_2 varchar(8196);
declare CQ varchar(1);
declare CR varchar(1);
declare LF varchar(1);
declare A_NAME varchar(50);
declare arch_id int;
declare arch_per varchar(6);
declare arch_server varchar(1024);
declare path_archiv varchar(512);
begin
CQ = ASCII_CHAR(39);
CR = ASCII_CHAR(13);
LF = ASCII_CHAR(10);
auser='SYSDBA';
apass='пароль';
SQL_1='CREATE DOMAIN D_INT AS INTEGER';
SQL_2='ALTER TABLE E_CONT ADD CONTSTR VARCHAR(12) COLLATE WIN1251_UA';
--
for
SELECT FIRST 1 'D:\DATA\Work1\', 'Work1' FROM MON$DATABASE UNION ALL
SELECT FIRST 1 'D:\DATA\Work2\', 'Work2' FROM MON$DATABASE
into :path_archiv, :city
do begin
path_archiv=trim(:path_archiv)||'archiv.gdb';
for
execute statement ('select path,server from archives where Upper(per)<>'||CQ||'DEF'||CQ)
ON EXTERNAL :PATH_ARCHIV AS USER :AUSER PASSWORD :APASS
into :A_PATH, :A_SERV
do begin
--
EXECUTE STATEMENT (:SQL_1) ON EXTERNAL :A_SERV||':'||:A_PATH AS USER :AUSER PASSWORD :APASS WITH AUTONOMOUS TRANSACTION;
EXECUTE STATEMENT (:SQL_2) ON EXTERNAL :A_SERV||':'||:A_PATH AS USER :AUSER PASSWORD :APASS WITH AUTONOMOUS TRANSACTION;
--
SUSPEND;
end
end
--
end
Автор: noisy
Дата сообщения: 12.12.2012 12:43
victor_r

Проверить есть ли в E_CONT CONTSTR
и если нет, выполнить запрос
Автор: victor_r
Дата сообщения: 12.12.2012 13:32
Спасибо noisy я так и сделал, вот мой рабочий вариант (лишнее повырезал):

Код:
SQL_1='SELECT rdb$field_name'
||' FROM rdb$relation_fields'
||' WHERE UPPER(rdb$relation_name)='||CQ||'ES_HOUSE'||CQ
||' AND UPPER(rdb$field_name)='||CQ||'CITYID'||CQ;
SQL_2='ALTER TABLE ES_HOUSE ADD CITYID INTEGER';

SQL_3='SELECT rdb$field_name FROM rdb$fields'
||' WHERE rdb$system_flag=0 and rdb$field_name='||CQ||'D_INT'||CQ;
SQL_4='CREATE DOMAIN D_INT AS INTEGER';
...
--
S_FIELDS=null;
EXECUTE STATEMENT (:SQL_1) ON EXTERNAL :A_SERV||':'||:A_PATH AS USER :AUSER PASSWORD :APASS
WITH AUTONOMOUS TRANSACTION
INTO :S_FIELDS;
S_FIELDS=trim(coalesce(S_FIELDS,''));
if (S_FIELDS='')
then begin
EXECUTE STATEMENT (:SQL_2) ON EXTERNAL :A_SERV||':'||:A_PATH AS USER :AUSER PASSWORD :APASS
WITH AUTONOMOUS TRANSACTION;
end
Автор: salexn1
Дата сообщения: 12.12.2012 14:45
victor_r
Прокатит, если в скриптах обновления нет скрипта для изменения данных.
Если же есть - то так не достаточно.
Нужно где-то хранить номер последнего обновления и стартовать с последнего.
Автор: miwa
Дата сообщения: 14.12.2012 16:17
salexn1
+1 насчет хранения номера последнего изменения. Правда, лично я храню также дату-время накатки каждого обновления - пару раз такая информация сохранила кучу времени.

Добавлено:
victor_r
Кстати, рекомендую разделить обновление на два скрипта - в одном только SQL, во втором - подключения и вызовы первого скрипта. Оно так логичнее.
Автор: salexn1
Дата сообщения: 14.12.2012 16:34
miwa
я для себя выработал правило: один апдейт(скрипт) на один номер.
я также храню дату и время.
Автор: YuriyRR
Дата сообщения: 15.12.2012 02:04
AlexPetrovich

Цитата:
[/q]
[q]Ага, счаз.
Приведи пример запроса определения начисленной суммы за услугу, если тариф менялся несколько раз за период ?

Привожу запрос тарифа на дату:
SELECT FIRST 1 TARIF FROM TARIFS WHERE DATA_TARIF <= ТРЕБУЕМАЯ ДАТА
ORDER BY DATA_TARIF DESC
заводим только нужный индекс
Автор: AlexPetrovich
Дата сообщения: 19.12.2012 09:05

Цитата:
Привожу запрос тарифа на дату:
SELECT FIRST 1 TARIF FROM TARIFS WHERE DATA_TARIF <= ТРЕБУЕМАЯ ДАТА
ORDER BY DATA_TARIF DESC
заводим только нужный индекс


Ага, счаз
Запрос хороший, но надо было "начисленной суммы за услугу",
сам по себе тариф мало когда нужен, главное деньги с клиента

Т.е. есть таблица "дата, количество" и таблица "дата, тариф",
надо получить, например, "итого сумма за месяц".
Попробуй это решить через "first 1".

А вот если таблица тарифов имеет две даты, то все просто и БЫСТРО:

select (usluga.kol_vo * tarifs.tarif)
from usluga
join tarifs on (usluga.data between tarifs.data_begin and tarifs.data_end)
where (usluga.data between '01.01.2012' and '01.02.2012')
Автор: YuriyRR
Дата сообщения: 19.12.2012 16:25
AlexPetrovich

Цитата:
Ага, счаз

SELECT USLUGA * (SELECT FIRST 1 TAR FROM tarif WHERE DT <= U.dt ORDER BY DT DESC)
FROM USL U
теперь согласен со мной? )))

Цитата:
то все просто и БЫСТРО

я больше экпериментально на массивах данных проверяю эффективность запросов
но что-то мне подсказывает что быстрый подселект уделает джоин по битвин как тузик грелку
хотя в этой задаче вообще без разницы
Автор: salexn1
Дата сообщения: 20.12.2012 09:49
YuriyRR
[q]SELECT  USLUGA * (SELECT FIRST 1 TAR FROM tarif WHERE DT <= U.dt ORDER BY DT DESC)  
FROM USL U


Вы уверены, что этот запрос валидный????
Автор: YuriyRR
Дата сообщения: 23.12.2012 04:04
да.
Автор: delover
Дата сообщения: 22.01.2013 17:02
Скажите ошибка BLR offset только при косяках с UDF-кой или ещё возникает?
Автор: exteris
Дата сообщения: 23.01.2013 07:41
delover
В процедурах и вьюхах тоже бывает.
Автор: delover
Дата сообщения: 23.01.2013 08:14
exteris
Спасибо, а то я иногда забываю какие причины этой ошибки надо копать.
Автор: deks
Дата сообщения: 14.02.2013 13:42
перенесено - из XE3-Варез ...

Neogar

Именно Boolean тип есть в firebird 3 _http://tracker.firebirdsql.org/browse/CORE-726

Однако многие (почти все?) клиентские библиотеки (FibPlus, AnyDAC, IBDac) реализуют тип Boolean на клиенте, если в имени домена для поля есть BOOL/BOOLEAN. Например, _http://www.da-soft.com/anydac/docu/frames.html?frmname=topic&frmfile=Extended_Metadata.html

Так что достаточно объявить правильный домен.

dortmund

Что не так с транзакциями в Firebird? Не в курсе.

Ну и "Firebird vs Interbase" - почти в 100% случаев Interbase можно тупо мигрировать в Firebird.

X11

Шифрование БД? Для Firebird 3 реализовано: _http://tracker.firebirdsql.org/browse/CORE-657

Для ранних версий - только на уровне файловой системы.
Автор: X11
Дата сообщения: 14.02.2013 13:48
Ну firebird 3 ещё ждать и ждать
Автор: ant0ni02004
Дата сообщения: 14.02.2013 16:26
deks
шифрование БД это хорошо конечно...
не говоря даже о том что пароль светится в SQL будет постоянно -
как по таким полям, например, индексы строить (а без индекса искать плохо) ?

Автор: deks
Дата сообщения: 15.02.2013 08:49
ant0ni02004

Детали реализации такого широкого понятия как "шифрование БД" не ясны!

Шифрование можно понимать так - только database engine может прочитать файл БД, и "украсть" файл и прочитать его невозможно. Тогда пароль достаточно указать при подключении БД, а оно может быть сделано по закрытому каналу.

Дальше есть детали реализации - будут ли шифроваться метаданные, данные? Можно ли шифровать отдельные данные, а отдельные - нет.. Пока деталей не видел! Кто видел - пускай дает наводку))
Автор: OXDBA
Дата сообщения: 15.02.2013 10:06
ant0ni02004

Цитата:
как по таким полям, например, индексы строить

Точно так же, как и сейчас

Код: CREATE [UNIQUE] [{ASC[ENDING] | DESC[ENDING]}] INDEX <index_name> ON <table_name>
COMPUTED [BY] ( <value_expression> )
Автор: ant0ni02004
Дата сообщения: 15.02.2013 14:10
deks
так детали и реализация шифрования БД - как раз есть самое интересное

Цитата:
"украсть" файл и прочитать его невозможно

для этого PGP-disk наверное лучше подойдёт
OXDBA
computed by decrypt()? можно, но это засветит пароль
кроме того в некоторых случаях всё равно поиск придётся делать аналогично, т.е.
where decrypt()=....
Автор: deks
Дата сообщения: 15.02.2013 15:07
ant0ni02004


Цитата:
PGP-disk наверное лучше подойдёт


Когда PGP диск смонтирован, на нем можно прочитать любые данные. Риск кражи файла БД в том, что "взламывается" сервер и получается доступ к файловой системе - тогда можно тупо скачать файл БД, даже если он на PGP диске.

Не могу сходу придумать условия, когда и от чего спасает PGP диск.

Вот шифрование на уровне ОС типа BitLocker - спасает при доступе к компу, но не к учетной записи: тогда сервер БД может быть запущен как сервис, и иметь свой доступ к шифрованному разделу диска! А злоумышленник типа данные прочитать не сможет

Автор: ant0ni02004
Дата сообщения: 15.02.2013 19:17
deks
права на файл/папку с файлами БД отдаются только сервису firebird - и никто его не заберёт (разве что не хакнут саму учетку админа)

а спасает, например, от кражи компьютера/жесткого диска
Автор: delover
Дата сообщения: 06.03.2013 06:48
Подскажите пожалуйста как можно поправить генератор. Просто когда поставили клиенту на справочнике не было генератора, а так как я не знаю добавят ли они ещё в справочник чего нибудь, мне нужно вычислить значение и установить. Для этого я пишу временную сохранёнку. Однако ругается на ALTER. Думаю что так нельзя делать, но как через RDB поправить, пока не разобрался.


Код: CREATE OR ALTER procedure RESTORE_PRICETYPE_GEN
as
declare variable ID integer;
begin
select max(PRICETYPE_ID) from PRICETYPE into :ID;
ID=:ID + 1;
ALTER SEQUENCE GEN_PRICETYPE_ID RESTART WITH :ID;
end
Автор: delover
Дата сообщения: 12.03.2013 18:40
Я легко отделался
ID = GEN_ID(:ID)
Но это потому что у меня создание генератора в том же скрипте. Далее отдаю в техпохдержку и там всё на удачу. А есть ли способ задать точное значение а не прибавить? Всё таки интересно! Я не гуру, помогите с лекарством от всего.
Автор: miwa
Дата сообщения: 12.03.2013 19:34
delover

Код:
alter sequence YOUR_GENERATOR_NAME restart with 12345;
Автор: YuriyRR
Дата сообщения: 13.03.2013 00:47
delover

Цитата:
Может кто нибудь знает как это правильно делать?

Зачем тебе генераторы для всех справочников.
Лучший случай один на всё.
Используй существующий, подумай о репликации данных.
Автор: miwa
Дата сообщения: 13.03.2013 01:25
YuriyRR
Если уж так серьезно думать об репликации, тогда лучше GUID вместо генератора.
Автор: deks
Дата сообщения: 13.03.2013 09:26
miwa

Про репликацию с GUID - святые слова!

Иначе все кончается таблицами соответствия ключей: в базе-клоне ключ такой, а в базе-мастере эта же запись с другим ключем. GUID в данном контексте рулит.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

Предыдущая тема: Сравнение двух строк


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.