Выделить число из строки

vso
Дата: 26.07.2012 17:52:31
Всем привет!

есть строки содержащие числа, например: 1А, 8В, 10С, 5/3 и т.д.

мне нужно получить число из этих строк, причем до первого не числового символа. Есть ли такая возможность в firebird?????

Поясню зачем, мне нужно отсортировать значения в запросе и я хочу к числу меньшему 10 приставить 0 (нолик), чтобы сортировалось правильно. А то, например, если этого не делать то 10А будет выше чем 8А.
Dimitry Sibiryakov
Дата: 26.07.2012 18:13:46

Веткин Сергей
Поясню зачем, мне нужно отсортировать значения в запросе и я хочу к числу меньшему 10
приставить 0 (нолик), чтобы сортировалось правильно. А то, например, если этого не делать
то 10А будет выше чем 8А.

Не будет если использовать COLLATE с атрибутом NUMERIC-SORT=1.

Posted via ActualForum NNTP Server 1.5

Таблоид
Дата: 26.07.2012 18:58:01
Веткин Сергей,

если строки не содержат первыми символами знак минус или пробел, то создайте коллацию с атрибутом numeric-sort=1 (как выше сказал DS). Затем используйте эту коллацию для сортировки строк: например, предварительно создав таблицу с полем чарсета utf8 и ранее созданной коллацией, либо просто через cast.
Но! примите к сведению, что при наличии в первых символах строк чего-то "нецифрового" (даже пробелов или знаков "минус") такие строки будут упорядочиваться весьма странно.
Вот пример для случая, когда строки хранятся в таблице с обычным чарсетом win-1251 и кастуются к utf8 для послед. сортировки:
recreate table tns(f int); -- drop dependencies if any
commit;
set term ^;
execute block as
begin
  execute statement 'drop collation ns_coll;';
  when any do begin end
end^
set term ;^
commit;
create collation ns_coll for utf8 from unicode 'NUMERIC-SORT=1';
commit;
recreate table tns(s varchar(50) character set win1251);
commit;

insert into tns values('1A');
insert into tns values('10C');
insert into tns values('8B');

insert into tns values('   1A');
insert into tns values('     10C');
insert into tns values('  8B');

insert into tns values('        -1A');
insert into tns values('    -10C');
insert into tns values('   -8B');

commit;


Test:
SQL> show version;
ISQL Version: WI-V2.5.2.26496 Firebird 2.5
Server version:
Firebird/x86/Windows NT (access method), version "WI-V2.5.2.26496 Firebird 2.5"
Firebird/x86/Windows NT (remote server), version "WI-V2.5.2.26496 Firebird 2.5/XNet (CSPROG)/P12"
Firebird/x86/Windows NT (remote interface), version "WI-V2.5.2.26496 Firebird 2.5/XNet (CSPROG)/P12"
on disk structure version 11.2
SQL> set width sx 50;
SQL> select cast(s as varchar(20) character set utf8) sx from tns order by 1 collate ns_coll;

SX
==================================================
-1A
10C
-10C
-8B
1A
8B
1A
8B
10C

ЗЫ. ИМХО, при юзании numeric-sort=1 с лидирующими пробелами и знаком минус (допустимыми при обычном cast(... as int)) имеется какая-то проблема.
Гаджимурадов Рустам
Дата: 26.07.2012 20:12:46

Таблоид

Не пиши "коллацию". Лучше пиши collation.

Posted via ActualForum NNTP Server 1.5

vso
Дата: 27.07.2012 16:19:35
Спасибо, за советы я помимо этого пытался еще написать udf функцию.

Что удивительно тестирую на дельфе все работает, компилирую и подключаю в firebird возвращает одни нули.

Вот что я написал на дельфи:

function ValX(CString: PChar): Integer; cdecl; export;
var
 I, Code: Integer;
begin
  Val(StrPas(CString), I, Code);
 
  Result := I;
end;


так я ее объявил в firebird:

DECLARE EXTERNAL FUNCTION VAL
    VARCHAR(256)
RETURNS INTEGER BY VALUE
ENTRY_POINT 'ValX' MODULE_NAME 'UDFDemo';


Как тестировал в дельфи:

Создал форму, на нее бросил Edit, Button и Label.

Повесил событие на нажатие кнопки, в едит ввожу данные, нажимаю на кнопку и в лабл виже результат который ожидаю.

А как только использую в firebird получаю одни нули????
Микросекунда
Дата: 27.07.2012 16:26:14
Веткин Сергей пишет:

> function ValX(CString: PChar): Integer; cdecl; export;

> DECLARE EXTERNAL FUNCTION VAL
> VARCHAR(256)
> RETURNS INTEGER BY VALUE
> ENTRY_POINT 'ValX' MODULE_NAME 'UDFDemo';

Posted via ActualForum NNTP Server 1.5

Dimitry Sibiryakov
Дата: 27.07.2012 17:33:19

Веткин Сергей
Повесил событие на нажатие кнопки, в едит ввожу данные, нажимаю на кнопку и в лабл виже
результат который ожидаю.

Потому что ты забыл преобразовать дельфийский String в VARCHAR.

Posted via ActualForum NNTP Server 1.5

vso
Дата: 30.07.2012 10:09:03
Dimitry Sibiryakov
Потому что ты забыл преобразовать дельфийский String в VARCHAR.


вообще-то я возвращаю Integer
vso
Дата: 30.07.2012 10:10:09
Микросекунда,

Поясни, пожалуйста, что ты хотел сказать этим выделением?
Микросекунда
Дата: 30.07.2012 12:29:49
Веткин Сергей пишет:

> Поясни, пожалуйста, что ты хотел сказать этим выделением?

http://www.ibase.ru/devinfo/udf_ok.htm
! char и varchar в InterBase и Firebird имеют свою специфику хранения, поэтому они не являются чистым эквивалентом PChar, это будет видно дальше в примерах. Для самой простой обработки строк всегда декларируйте строковые параметры функций как CSTRING, а в udf работайте с ними как с PCHAR. Передавать в такие функции вы сможете как CHAR так и VARCHAR, без изменения кода udf или объявления функции.


И еще тут читать: http://www.ibase.ru/devinfo/udf_safe.htm

Posted via ActualForum NNTP Server 1.5