Страница 1 из 1

UDF, NUMERIC,DOUBLE PRECISION

Добавлено: 15 авг 2006, 11:50
stix-s
наваял я UDF, которая возвращает мне сумму прописью ради эксперимента объявил ее по разному
1-

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

DECLARE EXTERNAL FUNCTION SUMTOTEXT
    NUMERIC(15,
    2),
    INTEGER,
    CSTRING(2048)
RETURNS CSTRING(2048)
ENTRY_POINT 'TextSumm' MODULE_NAME 'All_my_udf'
2-

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

DECLARE EXTERNAL FUNCTION SUMTOTEXT2
    DOUBLE PRECISION,
    INTEGER,
    CSTRING(2048)
RETURNS CSTRING(2048)
ENTRY_POINT 'TextSumm' MODULE_NAME 'All_my_udf'
при выполнении запроса

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

select first 1
sumtotext(123456789.33,1,'XXXXXXX'),
sumtotext2(123456789.33,1,'XXXXXXX')
 from gorod
получаются весьма разные результаты :(
sumtotext=Шесть рублей 09 копеек
sumtotext2=Сто двадцать тpи миллиона четыреста пятьдесят шесть тысяч семьсот восемьдесят девять рублей 33 копейки
в первом случае в функцию передается значение 6.09......Е-304
во втором - то, что надо
фунция писана в дельфях и сумму принимает, как
function TextSumm(MySum:PDouble;show_00_kop:Pinteger;ResCHR:PChar): PChar; cdecl; export;
результат возвертается в ResCHR
не нравится функции, когда я в качестве параметра ей NUMERIC(15,
2) скармливаю, а ведь в базе так и планирую денежные величины хранить
гдеж я накривил-то?

Добавлено: 15 авг 2006, 12:28
kdv
наваял я UDF, которая возвращает мне сумму прописью ради эксперимента объявил ее по разному
у тебя диалект какой?

в любом случае, в объявлении udf могут быть только физические типы. numeric/decimal - маппируемый тип, в зависимости от разрядности и диалекта.
MySum:PDouble;show_00_kop:Pinteger;ResCHR:PChar
ты сюда заглядывал?
www.ibase.ru/devinfo/udf_ok.htm
а сюда?
http://www.ibase.ru/devinfo/udf_safe.htm

Добавлено: 15 авг 2006, 12:46
stix-s
kdv писал(а): у тебя диалект какой?
пардон, диалект 3 FB 1.5.3
kdv писал(а):в любом случае, в объявлении udf могут быть только физические типы. numeric/decimal - маппируемый тип, в зависимости от разрядности и диалекта.
следовательно придется так делать:

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

select sumtotext(cast(field as double precision)) from table,
где field NUMERIC(15, 2)
 
Угумс, сейчас снова перечитываю.
смущает немного
3. возврат строки, которая является входным параметром. Это "трюк", поскольку IB сам аллокирует память для входного параметра. Основные неудобства - размер выходной строки должен совпадать с размером входной, и невозможность использования этого метода если функция не содержит входных строковых параметров (или по типу эти параметры отличаются).
но, полагаю, что память выделяется по указанному размеру параметра, в моем случае 2048 байт, а не по фактическому размеру параметра, так что ИМХО, если выходная строка не больше входа, то вроде как ничего страшного нет

Добавлено: 15 авг 2006, 12:54
kdv
пардон, диалект 3 FB 1.5.3
ну так ёшкин кот, с чего ты взял, что numeric(15,2) в третьем диалекте это double precision? :)
следовательно придется так делать:
следовательно, надо написать udf, в которую передается int64, а не double precision. и почитать про разницу между целыми и вещественными числами :)

Добавлено: 15 авг 2006, 13:06
stix-s
kdv писал(а): следовательно, надо написать udf, в которую передается int64, а не double precision. и почитать про разницу между целыми и вещественными числами :)
почитать, никада не откажусь :)
только вот куды мне в INT64 копейки деть? :)

Добавлено: 15 авг 2006, 13:10
kdv
только вот куды мне в INT64 копейки деть?
еще раз - в третьем диалекте numeric любой размерности хранится только в виде целых чисел - smallint, integer, int64.

Добавлено: 15 авг 2006, 13:29
stix-s
kdv писал(а): еще раз - в третьем диалекте numeric любой размерности хранится только в виде целых чисел - smallint, integer, int64.
понял я, однако засада :(

Добавлено: 15 авг 2006, 14:18
WildSery
Интересно, зачем было изобретать

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

function TextSumm(MySum: PDouble; show_00_kop: Pinteger; ResCHR: PChar): PChar; cdecl; export;
если везде пишут

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

function TextSumm(var MySum: Double; var show_00_kop: Integer; ResCHR: PChar): PChar; cdecl; export;

Добавлено: 15 авг 2006, 14:23
Dimitry Sibiryakov
Не у всех хватает мужества закладываться на слабодокументированные фичи - такие как способ передачи переменных по ссылке.

Добавлено: 15 авг 2006, 15:15
stix-s
Dimitry Sibiryakov писал(а):Не у всех хватает мужества закладываться на слабодокументированные фичи - такие как способ передачи переменных по ссылке.
мммммм, эт намек - типа не связывайся? или связывайся, но с тщательной оглядкой? :)
мне как-то больше всего понравилось ч/з входной параметр строки вовращать

Добавлено: 15 авг 2006, 15:18
stix-s
WildSery писал(а):Интересно, зачем было изобретать

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

function TextSumm(MySum: PDouble; show_00_kop: Pinteger; ResCHR: PChar): PChar; cdecl; export;
если везде пишут

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

function TextSumm(var MySum: Double; var show_00_kop: Integer; ResCHR: PChar): PChar; cdecl; export;
кхм, могет ты тож по ссылкам пройдешься, что мне кдв рекомендовал?
и где это - везде? :)

Добавлено: 15 авг 2006, 16:51
kdv
мммммм, эт намек - типа не связывайся? или связывайся, но с тщательной оглядкой?
это намек, что перед тем как сочинять свою udf, неплохо посмотреть udf на сайте в качестве примеров.

Добавлено: 16 авг 2006, 15:18
WildSery
stix-s писал(а):кхм, могет ты тож по ссылкам пройдешься, что мне кдв рекомендовал?
и где это - везде? :)
Что ж. Давай пройдусь, раз настаиваешь.

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

function Add_A(var iSmall: SmallInt; var iLong: Integer): Integer; cdecl; export;
Где тут PSmallint или PInteger? Везде var. Что хоть и имеет тот же смысл, но ^Integer усложняет восприятие кода.
Насчёт выходного параметра - да, если по ссылке, то без PInteger не обойтись. Но тут же смотрим:
с серверами архитектуры SuperServer нельзя использовать такие udf ... В SuperServer значения можно возвращать только по значению ...
Можно, конечно, с dll всегда класть readme.txt с содержимым "Никогда не использовать на SS!!!", но если решение очевидно, зачем так делать?

Добавлено: 17 авг 2006, 06:19
stix-s
WildSery писал(а):function Add_A(var iSmall: SmallInt; var iLong: Integer): Integer; cdecl; export;[/code]Где тут PSmallint или PInteger? Везде var. Что хоть и имеет тот же смысл, но ^Integer усложняет восприятие кода.
Вот и я про тоже - результат тот же, только вид сбоку :)
Примечание: все передаваемые в UDF параметры всегда передаются по ссылке, т.е. должны быть объявлены как var или как указатели.
Лично для меня код прозрачнее, если кому-то захочется переделать - да за ради бога, мне исходника не жалко :) дело вкуса
правда для этой функции он до безобразия корявый ибо я его просто тупо с VBA переделал.
WildSery писал(а): Насчёт выходного параметра - да, если по ссылке, то без PInteger не обойтись.
1 - если посмотреть на объявления функции вверху - то видно, что первые два параметра ВХОДНЫЕ и ничего не возвращают.
с серверами архитектуры SuperServer нельзя использовать такие udf ... В SuperServer значения можно возвращать только по значению ...
2 - внимательно! Речь идет именно о ВОЗВРАТЕ! при условии использования глобальной переменной!
Скажем возвращать результат ч/з входной параметр тебе никто не запрещает :)
В SuperServer значения можно возвращать только по значению, по FREE_IT, или через входной параметр (см. дальше).
если уж цитировать, то полностью, а то смысл совершенно другой :)
WildSery писал(а): Можно, конечно, с dll всегда класть readme.txt с содержимым "Никогда не использовать на SS!!!", но если решение очевидно, зачем так делать?
неа, это не наш метод :) я как раз SS пользую :)
ЗЫ вообще-то дискуссия уже выходит за рамки вопроса :)

Добавлено: 17 авг 2006, 11:14
WildSery
2 stix-s:
Вижу, что ты так и недопонял, про что я говорю.
Я всего-навсего выразил своё отношение к использованию объектов-указателей, типа ^Integer, в программе, если есть более красивые и понятные не только пишущему этот код конструкции. И обосновал, что без них можно легко обходиться.

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

Добавлено: 17 авг 2006, 11:51
stix-s
WildSery писал(а): Вижу, что ты так и недопонял, про что я говорю.
как еще прикажешь понять подобное цитирование?
WildSery писал(а): с серверами архитектуры SuperServer нельзя использовать такие udf ... В SuperServer значения можно возвращать только по значению ...
WildSery писал(а): Я всего-навсего выразил своё отношение к использованию объектов-указателей, типа ^Integer, в программе, если есть более красивые и понятные не только пишущему этот код конструкции. И обосновал, что без них можно легко обходиться.
Если кому-то не понравится, вполне можно переписать :)
WildSery писал(а): И раз уж ты завёл разговор... Использование всяких "хаков" и "фичей" типа использования для возврата входного параметра добавляет гордости кодеру за свои глубокие знания,
Никогда не заявлял, что слишком много знаю :) знал бы, вопросов бы тут не задавал :)
и с каких это пор возврат значения ч/з входной параметр стал
"хаком" или "фичей" ? :)
Все. в этой теме более не живу, ибо флейм :)
ЗЫ Спасибо всем, ответившим по существу вопроса.

Добавлено: 18 авг 2006, 11:53
WildSery
stix-s писал(а):Если кому-то не понравится, вполне можно переписать :)
Мда. :( В нашем департаменте с таким отношением никто не задержится...
Без обид, к тебе никаких претензий, просто мысли вслух.
Извините за оффтоп.

Добавлено: 18 авг 2006, 15:42
CyberMax
Добавлю свои пять копеек :).
[quote=stix-s]и с каких это пор возврат значения ч/з входной параметр стал
"хаком" или "фичей" ?[/quote]
С тех самых пор, как параметр назвался "входным". Использование данной возможности - дурной тон.