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

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

Автор: OXDBA
Дата сообщения: 26.02.2014 12:27

Цитата:
Да, да. Но только он не лазил в RDB.

Туда IBE сам может залезть, например при изменении размера поля или домена типа varchar из интерфейса IBE

Цитата:
А можно ли в системных таблицах хранить свои данные? Всего спрятать ключик к базе - пометить.

Не надо туда пока лазить, а ключик можно и в обычной таблице "спрятать", среди 1-2 млн. "мусорных записей", хотя при желании, в FB можно найти все.
Автор: xpin2013
Дата сообщения: 26.02.2014 15:50

Цитата:
например при изменении размера поля

Я думаю он изменил Integer на домен NUM_INT


Цитата:
Не надо туда пока лазить


Цитата:
а ключик можно и в обычной таблице "спрятать",

Вы правы, нутром чувствую - правы. Про ключик - это у них один клиент скопировал базу и поставил в другой торговой точке. Скопировались все дисконтные накопления и после обмена все накопления удвоились))). Ну так это решается совершенно другими путями, - ключ вообще не надо прятать - хранить хоть в INI файле и делать его хардваре зависимым. В общем спасибо, у нас всё решилось.
Автор: YuriyRR
Дата сообщения: 06.03.2014 00:05
Как узнать тип параметра в запросах типа
если заранее неизвестен текст запроса
SELECT * FROM TABLE WHERE FL STARTING WITH : PRM
WHERE UPPERCASE(FL) = : PRM
WHERE FUNC(FLD) = : PRM
Автор: ant0ni02004
Дата сообщения: 06.03.2014 01:46
YuriyRR
думаю, что для этого придётся парсить SQL и вытягивать всю информацию из RDB*
Автор: YuriyRR
Дата сообщения: 06.03.2014 03:42
вот IB Expert ,к примеру, определяет что для
WHERE CAST(ROUND(N_OTOPL,0) AS INTEGER) = : PRM
параметр интегер
а для
WHERE ROUND(N_OTOPL,0) = : PRM
даубл
Автор: OXDBA
Дата сообщения: 06.03.2014 07:02
YuriyRR
Доступ к базе в приложении каким образом осуществляется?
Автор: YuriyRR
Дата сообщения: 06.03.2014 07:33
OXDBA
Через FIBplus
Автор: OXDBA
Дата сообщения: 06.03.2014 07:57
Тогда что мешает использовать MyFibDataSet.Params[N].isNumericType, isDateType и т.д. для препарированного запроса?

Добавлено:
YuriyRR
Извини, немного тебя обманул

Добавлено:
Попробуй через MyFibDataSet.Params[N].isNumericType(MyFibDataSet.Params[N].SQLType)
Автор: YuriyRR
Дата сообщения: 10.03.2014 10:59
OXDBA
по FibDataSet.Params[N].SQLType разобрал параметры.
перед препарированием делаю .Params.ClearValues чтобы параметры от предыдущего запроса не мешали. Может нужно удалять все параметры перед новым запросом? Не нашел как?
Автор: OXDBA
Дата сообщения: 11.03.2014 07:58
YuriyRR
Вообще-то это вопросы по компонентам, а не по работе IB/FB. После изменения текста запроса, параметры очищать не нужно, далее, в FIB'ах метод Prepare будет вызван автоматически, перед первым выполнением запроса, поэтому, как правило, явно его не вызывают
Автор: xpin2013
Дата сообщения: 11.03.2014 10:36
Помогите пожалуйста с форматами integer и numeric. Сначала:

SUM_ROZN_REAL numeric(18,6) = 2535.00
SUM_OPT_REAL numeric(18,6) = 0.01
r_percent numeric(16,2) = ((:SUM_ROZN_REAL/:SUM_OPT_REAL) - 1) * 100

При расчёте процента вылетает ошибка:
Integer overflow. The result of an integer operation caused the most significant bit of the result to carry.

Я посчитал r_percent = 25349900 то есть в двоичном формате = 182CF0C
Мы видим что верхний байт = 1, то есть 7 верхних битов свободны, либо я что то не понимаю. Ну то что сумма оптовая одна копейка это тоже у нас ошибка, так как цена то нулевая, не знаем откуда копейка прилетела. В общем

r_percent=cast(((:SUM_ROZN_REAL/:SUM_OPT_REAL) - 1) as numeric(16,2)) * 100;
работает без ошибок, но непонятно какой предел величин доступен в первом случае и как его определить.
Автор: noisy
Дата сообщения: 11.03.2014 12:00
xpin2013

numeric(18,6) / numeric(18,6) = numeric(18,6)

а numeric(18,6) не влазит в numeric(16,2), вот и ошибка

если делать преобразование, то естественно влазит в numeric(16,2)

вывод - приведите типы в порядок
Автор: YuriyRR
Дата сообщения: 11.03.2014 16:52
OXDBA

Цитата:
После изменения текста запроса, параметры очищать не нужно

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

Цитата:
Prepare будет вызван автоматически, перед первым выполнением запроса, поэтому, как правило, явно его не вызывают

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

Цитата:
Вообще-то это вопросы по компонентам, а не по работе IB/FB.
Все начиналось с параметров запроса ФБ без всяких компонентов... как-то так
Автор: xpin2013
Дата сообщения: 11.03.2014 17:07
noisy

Цитата:
а numeric(18,6) не влазит в numeric(16,2), вот и ошибка

Не пишите мне отписки, пожалуйста. Этот говнокод написал я. Не Вася, Петя, Маша, Юля, которые были до меня в проекте. Этот бажный код написал я, тупой старый программист. Который рад увидеть свою ошибку, но не знает что с ней делать?

Вот вам лентяи:

Код: [no]CREATE OR ALTER procedure NEW_PROCEDURE8
returns (
R_PERCENT numeric(18,6))
as
declare variable SUM_ROZN_REAL numeric(18,6);
declare variable SUM_OPT_REAL numeric(18,6);
begin
SUM_ROZN_REAL = 2535.00;
SUM_OPT_REAL = 0.01;
r_percent = ((:SUM_ROZN_REAL/:SUM_OPT_REAL) - 1) * 100;
suspend;
end^
[/no]
Автор: noisy
Дата сообщения: 11.03.2014 18:23
изначально то он указан

Цитата:
r_percent numeric(16,2)


но конечно это не объясняет ошибку,
это код будет работать
r_percent = :SUM_ROZN_REAL/:SUM_OPT_REAL - 1;
r_percent = r_percent * 100;

[more=Масштабируемые типы с фиксированной точкой]

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

Предсказуемость результатов умножения и деления чисел с фиксированной точкой позволяет выбрать их для хранения денежных значений. Тем не менее, поскольку типы с фиксированной точкой имеют ограниченные "рамки", в которых могут размещаться числа, они являются причиной появления исключений переполнения или потери значимости возле их верхней и нижней границы. В странах, где единицы валюты представляют небольшие значения, нужно быть внимательным при выборе ограничений чисел.

Например, следующий оператор использует ставку налога (DECIMAL(5,4)) и чистую прибыль (NUMERIC (18, 2)):

UPDATE ATABLE

SET INCOME_AFTER_TAX = NET_PROFIT - (NET_PROFIT * TAX_RATE) ;

Пусть ставка налога будет 0.3333.

Пусть чистая прибыль будет 1234567890123456.78.

Результат:

ISC ERROR CODE:335544779

Integer overflow. The result of an integer operation caused the most significant bit of the result to carry.

(Переполнение целого числа. Результат целочисленной операции привел к переносу большинства значащих битов)

Firebird предоставляет два типа данных чисел с фиксированной точкой или масштабируемых: NUMERIC и DECIMAL. Каждый масштабируемый тип объявляется как TYPE(p, s), где p определяет точность (количество значащих цифр), а s - масштаб (размещение десятичной точки - т. е. количество цифр справа от символа десятичной точки).

В соответствии со стандартом SQL-92 оба типа NUMERIC и DECIMAL ограничивают хранимое число объявленным масштабом. Различие между этими двумя типами заключается в способе, каким ограничивается точность. Точность должна быть такой, "как объявлено" для столбцов типа NUMERIC, в то время как столбцы DECIMAL могут получать числа, чья точность по меньшей мере равна тому, что было объявлено, больше границы реализации.

Типы NUMERIC и DECIMAL, как они реализованы в Firebird, являются идентичными, за исключение случая, когда точность меньше пяти. Оба типа действительно соответствуют стандарту типа DECIMAL, NUMERIC не соответствует SQL-92.

Внутренне Firebird хранит масштабированное число как типы SMALLINT(16 бит), INTEGER (32 бита) или BIGINT(64 бита) в соответствии с объявленным размером точности. Его объявленная точность[21] сохраняется вместе с объявленным масштабом в виде отрицательного множителя масштаба[22], представляющего степень числа 10. Когда к числу происходит обращение для вывода или для расчетов, оно получается произведением хранимого целого на 10 в степени "множитель масштаба" ( 10(^множитель масштаба^) )

Например, для столбца, объявленного как NUMERIC(4,3), Firebird сохраняет внутренне число в виде SMALLINT. Если вы вводите число 7.2345, Firebird без сообщений округляет самую правую цифру (4) и сохраняет 16-битовое целое 7235 и множитель масштаба -3. Это число будет найдено как 7.235 (7235 * 10(^-3^)).[/more]
Автор: xpin2013
Дата сообщения: 11.03.2014 18:56
noisy
Ну да, будет работать, я хочу понять, как определить именно в моём выражении допустимые числа. Я ошибся на 6 бит - это больше чем три нуля допуска. Я ошибся более чем на тысячу в умножении. Вы можете определить допустимые величины для моей строки?

Хорошо. По ссылке Вы много написали, много, но я уже почувствовал направление - куда мыслить. Я хочу именно для моего выражения, именно с моими числами, определить допустимый диапазон. Я ошибся на 6 бит в умножении...

TypeCast-инг (преобразование типов). Результирующий тип - numeric(18,6), предупреждаю, разницы никакой decimal или numeric. Все равно ошибка, почему?????????????????????????????????????????????????????????????????????????

Добавлено:
noisy

Цитата:
изначально то он указан

не указан, указывайте любой

Добавлено:
Хорошо, почему ошибка?

Код:
SET TERM ^ ;

CREATE OR ALTER procedure NEW_PROCEDURE8
returns (
R_PERCENT decimal(18,6))
as
declare variable SUM_ROZN_REAL decimal(18,6);
declare variable SUM_OPT_REAL decimal(18,6);
begin
SUM_ROZN_REAL = 1035.00;
SUM_OPT_REAL = 0.01;
r_percent = (:SUM_ROZN_REAL/SUM_OPT_REAL - 1) * 100;
suspend;
end
^

SET TERM ; ^
Автор: YuriyRR
Дата сообщения: 12.03.2014 04:56
xpin2013

Код: [no]CREATE OR ALTER procedure NEW_PROCEDURE8
returns (
R_PERCENT numeric(18,6))
as
declare variable SUM_ROZN_REAL numeric(18,6);
declare variable SUM_OPT_REAL numeric(18,6);
begin
SUM_ROZN_REAL = 2535.00;
SUM_OPT_REAL = 0.01;
r_percent = ((:SUM_ROZN_REAL/:SUM_OPT_REAL) - 1) * 100;
suspend;
end^
[/no]
Автор: xpin2013
Дата сообщения: 12.03.2014 06:11
YuriyRR

Я сейчас попытаюсь вычислить свободные биты. У меня FB25, самая лучшая из версий.

Добавлено:
Вот последний вариант:

Код: SET TERM ^ ;
CREATE OR ALTER procedure NEW_PROCEDURE8
returns (
R_PERCENT numeric(18,6))
as
declare variable SUM_ROZN_REAL numeric(18,6);
declare variable SUM_OPT_REAL numeric(18,6);
begin
SUM_ROZN_REAL = 922.34;
SUM_OPT_REAL = 0.01;
r_percent = ((:SUM_ROZN_REAL/:SUM_OPT_REAL) - 1) * 100;
suspend;
end^
SET TERM ; ^
Автор: YuriyRR
Дата сообщения: 12.03.2014 07:37
xpin2013

Цитата:
Это работает а если напишем 922.35, то будет ошибка.

В ИБ эксперте на ФБ 2.05 после того как написал 922,35
запрос select * from new_procedure8 выдал ошибку, а после переконнекта все ок.
Автор: exteris
Дата сообщения: 12.03.2014 08:14
xpin2013
Почитайте как хранятся нумерики в 3-м диалекте.
Maxlonging = 9223372036854775807
В первом случае(SUM_ROZN_REAL = 922.34) результат помещается в этот лимит, во втором нет.
Автор: xpin2013
Дата сообщения: 12.03.2014 09:01
exteris
))) О спасибо! Начинаю понимать значение этих циферок...

Добавлено:
А где можно почитать, ссылочку бы от Вас.

Добавлено:
YuriyRR

Цитата:
а после переконнекта все ок.

У меня после переконнекта ошибка осталась.
Автор: exteris
Дата сообщения: 12.03.2014 09:51
Кое что на английском описано ТУТ
Автор: xpin2013
Дата сообщения: 12.03.2014 10:10
Спасибо! Но кстати, там это мало что объясняет. Если int результат 9223300, то непонятно откуда у него взялись дополнительные 12 символов сзади. Число то мы нашли, а вот почему внутренние преобразования 2 раза умножить на 100 дали такую гигантскую цифру не ясно.

Добавлено:
Дело в том что они пишут про NUMERIC(18,S) - что это 8 байтов. А вот DOUBLE PRECISION это мол нормальный для паскаля Double.

Добавлено:
Добавлю http://www.firebirdfaq.org/faq207/
Автор: noisy
Дата сообщения: 12.03.2014 10:31
xpin2013

хороший вопрос ты задал. я тоже, пока не нашел на него ответ.
хотя как хранятся числа в 3-м диалекте знаю, кстати почитать можно Хелен Борри. Firebird. РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ ,
но лучше книгу прикупить, что я и сделал


Цитата:
Maxlonging = 9223372036854775807

это не объясняет ошибку
почему даже при принудительном округлении
r_percent = (round(SUM_ROZN_REAL/SUM_OPT_REAL , 6) - 1) * 100;
выдает ошибку?

буду читать... пойму почему - напишу.


Автор: xpin2013
Дата сообщения: 12.03.2014 11:05
noisy

Цитата:
буду читать... пойму почему - напишу.

Пишите обязательно. Я вот думаю когда операция деления он рассчитывает мантиссу вверх с запасом шести знаков после запятой и когда /0.01=*100 происходит, тогда оказывается что мантисса выбрана не оптимально.
Автор: YuriyRR
Дата сообщения: 12.03.2014 13:50
declare @num1 numeric(38,10)
declare @num2 numeric(38,10)
set @num1 = .0000006
set @num2 = 1.0
select cast( @num1 * @num2 as numeric(38,10))

Дает: .0000010000
Вместо: .0000006000

(смотри Precision, Scale и Length) определяет следующие правила для арифметических операций c числами типа NUMERIC:
Операция     Точность результата     Масштаб результата *
e1 + e2     max(s1, s2) + max(p1-s1, p2-s2) + 1     max(s1, s2)
e1 - e2     max(s1, s2) + max(p1-s1, p2-s2) + 1     max(s1, s2)
e1 * e2     p1 + p2 + 1      s1 + s2
e1 / e2     p1 - s1 + s2 + max(6, s1 + p2 + 1)     max(6, s1 + p2 + 1)
e1 { UNION | EXCEPT | INTERSECT } e2     max(s1, s2) + max(p1-s1, p2-s2)     max(s1, s2)

В нашем случае точность и масштаб умножения вычисляется так:

Точность = P1 + P2 + 1 = 38 + 38 + 1 = 77
Масштаб = S1 + S2 = 10 + 10 = 20

Соответственно, результатом должно быть число типа numeric(77, 20), что не допускается. Вот где нам понадобится сноска:

* Точность и масштаб результата имеет абсолютный максимум 38. Если точность результата превышает 38, соответствующий масштаб уменьшается, чтобы предотвратить усечение целой части результата.
Автор: xpin2013
Дата сообщения: 12.03.2014 16:58
YuriyRR

Цитата:
превышает 38, соответствующий масштаб уменьшается

Во, здесь правильное слово "масштаб". В моём случае операция Int не имеет масштаба, по этому не очень удачный выбор.
Автор: Andryshok
Дата сообщения: 31.03.2014 14:35
Форумчане поделитесь плиз кто нибудь последней скомпилированной версией rFuncs для Firebird 2.5 и установочным скриптом для нее
Автор: noisy
Дата сообщения: 31.03.2014 15:29
Andryshok

пару страниц назад я писал

Цитата:
RFUNC тем более не советую, старая эта либа уже
современная замена RFUNC - AUDFL https://www.assembla.com/spaces/audfl_rfunc/documents

Автор: Andryshok
Дата сообщения: 31.03.2014 15:41
noisy
Спасибо, но что то при установке оной либы в базу (выполнение скрипта из файла function3.sql) вылазит ошибка

Код:
Undefined name.
Dynamic SQL Error.
SQL error code = -204.
Data type unknown.
Implementation limit exceeded.
COLUMN DSQL internal.

Страницы: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465

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


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