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

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

Автор: delover
Дата сообщения: 31.03.2012 05:37
noisy
Может у меня дальше валится, я не могу понять где у меня преобразование слетает, могу даже доступ по тимвиюверу дать или по аммиадмину.
Автор: ant0ni02004
Дата сообщения: 31.03.2012 16:35
delover

1. с какой ошибкой (точно номер и текст) слетает?
2. полный код ХП было бы хорошо увидеть
Автор: delover
Дата сообщения: 02.04.2012 07:02
Ура я вычислил место где всегда слетает.

Код: create or alter procedure NEW_PROCEDURE
returns (
KOL2 numeric(18,6))
as
declare variable CENA1 numeric(18,6);
declare variable STO numeric(18,6);
declare variable NACEN_OPT_NDS numeric(18,6);
declare variable KOL_ALL numeric(18,6);
begin
KOL_ALL = 2.0;
CENA1 = 2.036667;
sto = 100.0;
NACEN_OPT_NDS = 18.0;
KOL2 = ((:KOL_ALL*Round(:CENA1*:sto)/:sto)/:sto)*:NACEN_OPT_NDS;
suspend;
end^
Автор: exteris
Дата сообщения: 02.04.2012 10:29
delover
Переполнение количества знаков после запятой. У FB в 3-м диалекте точность при умножении numeric-чисел суммируется.
Автор: delover
Дата сообщения: 02.04.2012 13:27
exteris
Странно она суммируется. Вопервых при умножении количество точных чисел после запятой не будет увеличено. Во вторых только CENA1 имеет знаки после запятой у других чисел этих знаков нет. Ну и в третьих - способ борьбы с этим естественно необходим. У меня:

Код: ...
KOL2 = ((:KOL_ALL*Round(:CENA1*:sto)/:sto)/:sto);
KOL2 = KOL2*:NACEN_OPT_NDS;
Автор: exteris
Дата сообщения: 02.04.2012 14:06

Код:
create or alter procedure new_procedure
returns (
kol2 numeric(18,6))
as
declare variable a numeric(18,6);
begin
a = 2;
kol2 = a*a*a;
-- kol2 = a*a*a*a;
suspend;
end^
Автор: ant0ni02004
Дата сообщения: 02.04.2012 16:39
delover


Цитата:
если я убираю *:NACEN_OPT_NDS то ошибка исчезает


Цитата:
процедура не может умножить 0.040800 на 18.0


с одной стороны должно получится ровно 0,7344
а с другой там вполне может быть что-то типа 0,73499999999... что уже не влазит в (18,6)

попробуйте всё выражение завернуть в ROUND до 6 знаков после запятой

как-то так:

Код:
KOL2 = round(((:KOL_ALL*Round(:CENA1*:sto)/:sto)/:sto)*:NACEN_OPT_NDS,6);
Автор: delover
Дата сообщения: 02.04.2012 17:47
ant0ni02004
Это весело было бы просто шикарно, но более половины клиентов не хотят переходить на FireBird 2.5. Они ползают на 1.5, и SQL строится с учётом этого. Round с дополнительным параметром в 1.5 не работает, грехи мои тяжкие.

Добавлено:
exteris
Спасибо, реально натолкнуло мыслить в нужном направлении. Думаю экспрессии более 3х роскошь. Numeric так же как и тип Extended (в пример Delphi 64), я считаю очень достойными типами данных. Вполне состоятельные типы данных без влияния директората. Прежде чем оспаривать - предложу изучить типы с плавающей точкой в Linux. Extended конечно только Delphi компилятор знает, но в Linux есть тоже точные типы данных, но эта тема не для этого топика. Итог:

exteris - моя уважуха...
Автор: ant0ni02004
Дата сообщения: 02.04.2012 19:42
delover


Цитата:
Они ползают на 1.5

как я Вас понимаю... аналогичная фигня

для Firebird 1.5 есть UDF rfunc.dll, там "более правильный" round (и много чего другого)
Автор: delover
Дата сообщения: 03.05.2012 20:07
ant0ni02004
Благодарю

Фибрахи спасибо за фильтры


Добавлено:
А вопрос если ATD не корректный как от фибов узнать об ошибке?
Автор: SevereK20
Дата сообщения: 07.05.2012 10:03
Тема уже наверное 100500 изъезжена, но все же... подскажите, каким образом лучше всего реализовать автоинкремент?
FB 2.5 + Delphi 7. Пока лучше идеи генератора идей в голову не приходило..
p.s. RETURNING ID в делфе, насколько я понял, не поддерживается
Автор: X11
Дата сообщения: 07.05.2012 10:37

Цитата:
RETURNING ID в делфе, насколько я понял, не поддерживается

Дельфи тут при чем?
RETURNING ID - это SQL
в чем сложность-то?



Цитата:
каким образом лучше всего реализовать автоинкремент?

В огнептице генератор+триггер перед добавлением. И только такой будет путь будет наиболее правильный.
Автор: SevereK20
Дата сообщения: 07.05.2012 10:39
X11
А вытягивать значение добавленного поля каким образом? В триггере влупить возвращаемое значение?
Автор: X11
Дата сообщения: 07.05.2012 10:50
а что такое "значение добавленного поля" О_о
Автор: SevereK20
Дата сообщения: 07.05.2012 10:54
X11
В программе мы делаем запрос INSERT, не указывая ID, его нам делает триггер при помощи генератора. Но в программе нам надо получить этот ID, который только что был добавлен. В этом собственно говоря и вопрос. С returning id однозанчно какой-то подвох, потому что все жалуются, что его из квери не получается вытянуть.
Автор: X11
Дата сообщения: 07.05.2012 10:56
значение ключевого поля при добавлении новой записи можно получить примерно так

в запросе: insert .... returning ID

query.open(или execSQL)// добавляется запись
iNewID := query.Fields[0].AsInt64;//получаем новый ID (значение ключевого поля)
spTREKLAMA_INS.Close;//закрываем кверю

Что сложного?
Сложить в уме добавление записи INSERT + получение значения нужно поля SELECT (В данном случае returning)

Я уверен, что в тырнете есть примеры. Почему их не посмотреть?

Добавлено:

Цитата:
С returning id однозанчно какой-то подвох, потому что все жалуются, что его из квери не получается вытянуть.


ВСЕ???!!!!
Первый раз вижу такое сообщение!
И не нужно отвечать за всех пока сам не выучил матчасть.
Автор: SevereK20
Дата сообщения: 07.05.2012 11:21
X11
Все получилось. Спасибо. И чего ж я столько мучался-то.
Может, IBDAC кривой компонент был..
Спасибо еще раз.
Автор: delover
Дата сообщения: 09.05.2012 14:51
Автоинкремент конечно ключевое понятие, и проблемм с автоинкрементом нет ни в FIB-ах ни в стандартных IB нет их даже в Вижуал Студио+FB, тоже мне надо было. Однако матчасть по этому явлению родила много чего в чём легко заблудится. Например 3 автоинкремента на одну таблицу - зачем это может понадобиться? Простите ламера - имхо. Второе - если автоинкремент работает стабильно, те как положено, то это поле уникальное в принципе, даже для Int32 инкремента - это 4 миллиарда записей. (В FB базе с двумя таблицами по 3 миллиона уже сложно работать - ждёшь по 3 минуты так как все процедуры делает сервер и техподдержка - дело не в ФБ а в практике). Так вот почему автоинкрементное поле не индексируется изначально?

Ну и теперь запретная тема - индексы. Написав свою БД с индексами просто уже стало очевидно, что SQL - это язык запросов... ) Пользуватели пишут очень сложный математический SQL запрос который работает медленно потому что сервер вынужден делать за программиста предположения об использовании индекса. Масса примеров когда сервер неспособен вычленить из SQL запроса обязательное условие - мастер детейл, который сократит операцию по времени в 100 раз. В интербейзе 2 способа - писать OrderBy или Plan, но оба способа совершенно не подходят. OrderBy - теряет реальную последовательность, Plan - не вычленяет главного условия как мастер-детейл. Так что тут либо пользователи ущербны - либо SQL как язык запросов, не обеспечивающий требуемого быстродействия. В общем Автоинкремент оброс массой ненужного и не приобрёл полезного. В моей демонстрашке 3 миллиона записей по мастер детейлу фильтруются за одну миллисекунду примерно - глаз не замечает. При этом стандартный фильтр от Delphi делает это примерно минуту. Так что и выводы об необходимости первичного индекса в SQL запросе я уже сделал.

Добавлено:
Я бы расширил SQL язык просто из тех принципов что слова Master-Detail поймёт даже тех поддержка не умеющая писать план индексов. Даже из того что Мастер детайл это заведомо небольшое количество записей в считанные миллисикунды. И даже из того принципа что это заведомо экономит электроэнергию. Стандарт SQL не ставит похоже экономию электроэнергии, пока не ставит, на должное место.
Автор: X11
Дата сообщения: 09.05.2012 15:16

Цитата:
Так вот почему автоинкрементное поле не индексируется изначально?

индекс по ключевому полю создается автоматически

Код: ALTER TABLE OBJNAME ADD CONSTRAINT PK_OBJNAME PRIMARY KEY (ID);
Автор: delover
Дата сообщения: 09.05.2012 16:17
X11

Цитата:
индекс по ключевому полю создается автоматически

Да впереди я писал про автоинкремент - их может быть 8 автоинкрементов - ключевое поле одно. Да и вообще я пто такой SQL
[more]
Код: [no]END[/no]
Автор: delover
Дата сообщения: 09.05.2012 19:20
Это как в семье ((((. Я ей говорю - я мужик я сказал что тебя жду. Она говорит ага - щас уйду и ты заснёш.
Моё слово не дождался никто, но ладно у меня forewer, или forever.

Добавлено:
зы
Тему не афишируем - локальное индексирование на клиент датасете, и можно мимо багов.

Добавлено:
Это не основная моя мысль. Я хотел пообщаться вобщето. Баги не обязательное явление сейчас.

Добавлено:
Тема закрыта я не виноват
Автор: delover
Дата сообщения: 09.05.2012 21:33
Limp Bizkit - Take a Look Around
Автор: AlexCoRu
Дата сообщения: 09.05.2012 21:47

Цитата:
А SQL сервер тупо не знает что я оба поля задал.
???
Автор: SevereK20
Дата сообщения: 09.05.2012 22:08
в хорошее направление пошла беседа)))))
Автор: delover
Дата сообщения: 10.05.2012 04:16
AlexCoRu
Незнаю запрос один ковырял, как ни кручу - неиндексированное чтение. Выполняется долго, а по идее должен быстро. Когда смотрел таблицу - там составной примари, думаю из-за этого.

Добавлено:
Ага OrderBy пишу - схватывает индекс.

Добавлено:
Во ещё один запрос ковыряю - пишу OrderBy всё равно не индексированное чтение. Да мне хоть в каком порядке давай - юзай индексы. Я из одной хранимки другую for селектю и потом уже сортирую. Был бы я автором Файрборды я бы расцеловал юзера который мне бы сказал - хочу мастер-детайл показать.

Добавлено:
У меня проблеммы только с названием, то я хочу написать Майн, то я хочу написать Детайл. Похоже это главное препятствие к тому чтобы всем было лучше.
Автор: AlexPetrovich
Дата сообщения: 10.05.2012 13:08
delover
Чего-то ты какую-то ахинею пишешь...

Цитата:
Например 3 автоинкремента на одну таблицу - зачем это может понадобиться?

Да хоть 10. Это определяет разработчик в зависимости от решаемой задачи.

Цитата:
Так вот почему автоинкрементное поле не индексируется изначально?

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

Цитата:
Пользуватели пишут очень сложный математический SQL запрос который работает медленно потому что сервер вынужден делать за программиста предположения об использовании индекса.

А с какого перепугу "пользователи" пишут SQL-запросы ?? Дело пользователя кнопочки нажимать, а запросы должен составлять, отлаживать и оптимизировать разаработчик.
Сервер не делает предположений об использовании индекса - в зависимости от запроса он выбирает "оптимальный" план запроса. Если разработчика не устраивает полученный результат (скорость или еще чего) - значит надо модифицировать запрос, добавить (или убрать) индексы, модифицировать структуру БД.

Цитата:
Масса примеров когда сервер неспособен вычленить из SQL запроса обязательное условие - мастер детейл, который сократит операцию по времени в 100 раз. В интербейзе 2 способа - писать OrderBy или Plan, но оба способа совершенно не подходят. OrderBy - теряет реальную последовательность, Plan - не вычленяет главного условия как мастер-детейл.

Вообще муть какая-то... Сервер ничего не "вычленяет". Для мастер-детейл связок учитесь писать правильные запросы с использованием JOIN, FK и PK.
OrderBy задает всего лишь сортировку, причем сдесь мастер-детейл ?
"теряет реальную последовательность," - реальная последовательность это какая ?? Порядок хранения и извлечения данных в/из БД НЕ ОПРЕДЕЛЕН, т.е. идет вперемешку, если нжно упорядочивание - используйте "Order By"

Цитата:
пользователи ущербны - либо SQL как язык запросов, не обеспечивающий требуемого быстродействия

либо неграмотный разработчик...

Цитата:
Я бы расширил SQL язык

Вообще-то это стандарт, и практически всех устраивает. Слава Богу, что вы далеки от разработчиков этого стандарта...

ВЫВОД - RTFM! (Перед тем, как писать всякую муть на уважаемых ресурсах).
Автор: delover
Дата сообщения: 10.05.2012 14:43
AlexPetrovich
О, я люблю пошутить за это злюсь конечно на себя, но на этом вся ваша правота заканчивается. В ПМ могу скинуть ссылку на БД полностью в исходниках. По этому я смелюсь утверждать что знаю про что пишу не из теории...


Цитата:
Да хоть 10. Это определяет разработчик в зависимости от решаемой задачи.

Как разработчику мне ни разу не понадобилось в течении 20-и лет эта возможность.


Цитата:
Потому что сервер не должен "додумывать" за разработчика и заниматься "самодеятельностью".

То есть обязан лениться из принципа и быть далёким от реально возможной оптимизации.


Цитата:
А с какого перепугу "пользователи" пишут SQL-запросы ??

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

OnWhere - выполняет фильтрацию. OnJoin - выполняет добавление полей в выборку. Насколько знаю - сильно не бейте, сначала выполняется приджойнивание (условия джойна) а потом условия where - это справедливо для того чтобы в условиях могли присутствовать поля из всех таблиц запроса. Однако.

Та база пока что не сервер. И я смотрю как реализован Selet. О чудо OnWhere выполняется до OnJoin. Я понимаю автора - в клиентской базе все данные все таблицы уже доступны в OnWhere и нет просто смысла выполнять Join данных до выполнения Join условий которые доступны в событии OnWhere... Выборка мастер детейла на двух таблицах с тремя миллионами делается в миллисекунду. Это происходит за счёт того что в первую очередь выбирается правильный индекс. То есть - берётся индекс который высчитан по условию либо больше либо меньше либо если равно то либо больше либо меньше реальный RecNo. И вся выборка первично идёт из локейта на первую позицию по условию потом чтение пока условие true.

!!! Так вот когда я могу вычленить это условие из запроса Я могу делать выборку за одну миллисекунду на трёхмиллионных таблицах и далее делать дополнительную фильтрацию дубляж джойнами и условиями конечной фильтрации. И даже больше если вы дадите запрос groupBy я его интелектуально как девелопер разберу и выполню на тех же данных что и FB сервер в сотню раз быстрее, потому что именно вычленю оптимальное условие.


Цитата:
Вообще-то это стандарт, и практически всех устраивает. Слава Богу, что вы далеки от разработчиков этого стандарта...

Вы косо читали впереди я писал - сервер FB в посте выше был запрос делает 2 раза чтение в трёхмиллионных таблицах выбрав не те индексы. И он это делает когда я заранее знаю что он ничего не вернёт. Я пишу ПО далее отдаю в техподдержку которая его полгода мучает - отдает мне, после релиза мучается сама. Мои попытки реорганизовать в запросах план запроса не дали необходимых мне результатов, если вы внимательно читали что я пишу то понимаете почему - Join по 3 миллионам всегда идёт раньше чем первичное условие мастер-детайл.

ВЫВОД - Не кипятитесь теоретики, на уважаемых ресурсах. Я могу выложить все данные все ссылки все цыферки сравнения. Напишу инструкцию на русском как запустить и Вы никогда в жизни не добётесь этих же результатов на стандартном SQL    (Перед тем, как писать всякую муть на уважаемых ресурсах, славо богу если научитесь так же уважать себя). Я про экономию электроэнергии. Почему на уважаемом ресурсе не уважают экономию энергии тупо простаивающих компов?

ps
Девелопер не бог, всего учесть не может даже за полгода - результат еле ворочающиеся программы и безполезный в этом случае SQL, который можно было бы оптимизировать в 100 раз, абсолютно уверен.


Добавлено:


И В ПЕРВУЮ ОЧЕРЕДЬ SQL не устраивает из того принципа что сервер не должен делать предположений.
Автор: AlexPetrovich
Дата сообщения: 10.05.2012 14:57
delover
Извините, но я категорически не понимаю ваш поток сознания...
Удачи вам в разработке собственного SQL

Добавлено:
После просмотра ваших ссылок я вроде понял о чем вы...
То, что на локальной машине можно произвести выборку из локальных данных быстрее, чем это сделает SQL-сервер ? В это верю конечно. И изредка такой подход оправдан.
НО! Это имеет смысл только в очень узко применимых задачах, когда стандартные методы не работают.
Потому как теряется многопользовательская работа, транзакции, и проч.

Если вы уверены, что вашу задачу можно решить только так - ну что ж, вы разработчик, вам виднее.

Но это совсем не значит, что SQL-стандарт "плохой" и сервера БД "плохие".
Просто их тоже надо уметь использовать.
У меня в БД таблицы по 10 млн записей и все летает...
Автор: delover
Дата сообщения: 10.05.2012 15:31
AlexPetrovich

Цитата:
У меня в БД таблицы по 10 млн записей и все летает...

Почемуто я уверен что изначально Вы были разработчиком этого ПО. По этой причине всё летает. Я не прав? ) У меня обратная ситуация - я не разрабатывал ПО, я его обезглючиваю и оптимизирую. Рад что Вы увидели про что я писал, так как всю соль вы можете увидеть под отдалчиком в методе Select.


Цитата:
Но это совсем не значит, что SQL-стандарт "плохой" и сервера БД "плохие".

Вы шутите, SQL отличный и все сервера это дыхание богов я не спорю. Но шаманов у меня не будет это точно. Чем больше копал тем более ясно что вопрос реально сложный, а я не такой умный и сложностей не хочу.
Автор: delover
Дата сообщения: 11.05.2012 06:18
Уже в join запихивал условие даже OR убрал везде. Шаманю бестолку.

добавлено
под конец дня полностью разочаровался в своей идее. По крайней мере FireBird тут вряд ли оптимизируешь. У меня выигрыш был в миллисекундах на фоне двух секунд. Это было после того как выяснилось что селект идёт не на прямую из процедуры а именно в селект запросе с ордербай по апперкейс имени. Потом это скармливается гридине у которой уже стоит сортировка - она сортирует по другому. Потом Filtered := false когда он и так false. Потом блок который востанавливает сортирувку в других гридинах где это нужно востановить, то есть сортируется ещё раз. И потом видимо компоненты поменялись, потом считываются установки из реестра и сортируется ещё раз. То есть вместо 30 секунд стало делать за 9 секунд. Ну и я забил уже на миллисекунды.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

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


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