powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Informix [игнор отключен] [закрыт для гостей] / Как ограничить вводимые данные латинскими символами ?
13 сообщений из 13, страница 1 из 1
Как ограничить вводимые данные латинскими символами ?
    #38060713
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обращаюсь к коллективному разуму.
Дано : база в Unicode UTF8, клиент тоже, DB_LOCALE и CLIENT_LOCALE выставлены в en_us.utf8.
Таблица с lname char(50), fname char(50), и mid_init char(1).

Требуецца : ограничить вводимые данные латинскими символами, выдавать ошибку при попытке ввода других.

Текущее решение:
создаем процедуру

create procedure "informix".check_unicode ( p_str lvarchar(32000));

if p_str matches "*[^ -ÿ]*" then
raise exception -746, 0, "Illegal Unicode character in one of character fields";
return ;
end if
return ;
end procedure;


вешаем триггер:

create trigger tr_owner_person_ins insert on owner_person referencing new as new_tab
for each row
(
execute procedure check_unicode(
' ' ||
TRIM ( BOTH ' ' FROM NVL (new_tab.fname ,'' )) ||
TRIM ( BOTH ' ' FROM NVL (new_tab.lname ,'' )) ||
TRIM ( BOTH ' ' FROM NVL (new_tab.mid_init ,'' )) )
)

Тестируем:

update owner_person set lname = 'आ' where owner_number = 123 -- работает, выдает ошибку 746

update owner_person set mid_init = 'आ' where owner_number = 123 -- НЕ РАБОТАЕТ!!! Ошибку не выдает.

Причина, очевидно, в том что прежде чем вызывать процедуру, триггер собирает строку из _преобразованных до соответствующих длин_ новых значений. То есть 'आ' которое есть 0xE0A486 в UTF8 кодировке, превращается в 0x20 (пробел) и уже становится законным латинским символом.

Понятно, что накрайняк можно переделать char(1) в char(4) (кстати, похоже, Informix глючит на 4-битовых UTF8 кодах).
Any other ideas?
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38060805
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выбегалло, решение вроде на поверхности: в триггере 3 раза вызывать ХП, а не склеивать строку...
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38060808
АнатоЛой
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И почему пробелы только ведущие и замыкающие удаляются? Не проще ли их разрешить в позволяющей ХП?
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38060825
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойВыбегалло, решение вроде на поверхности: в триггере 3 раза вызывать ХП, а не склеивать строку...

Да хоть десять раз, пардон май френч. Информикс _сначала_ преобразует new value к типу поля (в нашем случае char(1)), потом будет вызывать что там в триггере прописано. При преобразовании он магически превращает трехбайтный Unicode символ в банальный пробел, кагбы намекая "ну не шмогла я, не шмогла"
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38060828
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АнатоЛойИ почему пробелы только ведущие и замыкающие удаляются? Не проще ли их разрешить в позволяющей ХП?

lvarchar(32000) конечно немало, но и не так уж много. Экономить приходится.
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38060942
victor16
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВыбегаллоПонятно, что накрайняк можно переделать char(1) в char(4) (кстати, похоже, Informix глючит на 4-битовых UTF8 кодах).
Any other ideas?

Конфигурационный параметр SQL_LOGICAL_CHAR установлен?
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38063603
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
victor16ВыбегаллоПонятно, что накрайняк можно переделать char(1) в char(4) (кстати, похоже, Informix глючит на 4-битовых UTF8 кодах).
Any other ideas?

Конфигурационный параметр SQL_LOGICAL_CHAR установлен?

Во-первых, этот параметр влияет только на DDL, определяя коэффициент умножения. Если в оригинале было create table t1 (col1 char(1)), то в зависимости от параметра и codeset мы можем получить col1 типа от char(1) до char(4). Это, конечно, зашибись - пока нас не интересуют размеры таблицы и максимальные длины строк. На поведение триггера и очередность преобразований параметр никак не влияет.

Во-вторых, че-то он у меня так и не заработал. Ни c SQL_LOGICAL_CHAR=ON, ни c SQL_LOGICAL_CHAR=4 - как было char(1) так и осталось.

create database test;

create table t2 (col1 varchar(1),
col2 char(1),
col3 char(5));

insert into t2 (col1) values ('आ');
insert into t2 (col2) values ('आ');
insert into t2 (col3) values ('आ');

select ascii(col1), ascii(col2), ascii(col3) from t2


(expression) (expression) (expression)

32
32
8824032
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38065109
victor16
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Выбегалло ... select ascii(col1), ascii(col2), ascii(col3) from t2 ...

А что, если вызвать функции LENGTH (also known as LEN), OCTET_LENGTH, CHAR_LENGTH (also known as CHARACTER_LENGTH)
Интересно, что они возвращают при установленном SQL_LOGICAL_CHAR ?
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38065250
victor16
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВыбегаллоКонфигурационный параметр SQL_LOGICAL_CHAR ... че-то он у меня так и не заработал.

У меня работает, только если он был установлен при создании базы. Если установить SQL_LOGICAL_CHAR после создания базы, не оказывает никакого влияния, как будто его нет.

Ниже Ваш SQL-скрипт, немного подправленный:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
drop table if exists t2;
create table t2 (col1 varchar(1),
col2 char(1),
col3 char(5)
);

insert into t2 (col1, col2, col3) values ('आ', 'आ', 'आ' );
insert into t2 (col1, col2, col3) values ('1', '1', '1' );

select col1, col2, col3, 
       "as utf8", ascii('आ'), LEN('आ'), OCTET_LENGTH('आ'), CHAR_LENGTH('आ'),
       "as ascii", ascii('1'), LEN('1'), OCTET_LENGTH('1'), CHAR_LENGTH('1'),
       "as varchar(1)", ascii(col1), LEN(col1), OCTET_LENGTH(col1), CHAR_LENGTH(col1),
       "as char(1)", ascii(col2), LEN(col2), OCTET_LENGTH(col2), CHAR_LENGTH(col2),
       "as char(5)", ascii(col3), LEN(col3), OCTET_LENGTH(col3), CHAR_LENGTH(col3)
from t2



Из результатов видно, что длины значений UTF8 и ASCII при установленном SQL_LOGICAL_CHAR=4 различаются.
Для читабельности оформил в виде таблицы:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SQL_LOGICAL_CHAR=OFF								
	UTF8 value				ASCII value			
col1						1			
col2						1			
col3	आ					1			
		ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH	ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH
as symbol	8824032	3	3		1		49	1	1		1
as varchar(1)	32	0	1		1		49	1	1		1
as char(1)	32	0	1		1		49	1	1		1
as char(5)	8824032	3	5		3		49	1	5		5

SQL_LOGICAL_CHAR=4								
	UTF8 value				ASCII value			
col1	आ					1			
col2	आ					1			
col3	आ					1			
		ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH	ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH
as symbol	8824032	3	3		1		49	1	1		1
as varchar(1)	8824032	3	3		1		49	1	1		1
as char(1)	8824032	3	3		1		49	1	3		3
as char(5)	8824032	3	15		13		49	1	15		15
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38065257
victor16
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
чего-то меня форматирование подвело :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
drop table if exists t2;
create table t2 (col1 varchar(1),
col2 char(1),
col3 char(5)
);

insert into t2 (col1, col2, col3) values ('आ', 'आ', 'आ' );
insert into t2 (col1, col2, col3) values ('1', '1', '1' );

select col1, col2, col3, 
       "as utf8", ascii('आ'), LEN('आ'), OCTET_LENGTH('आ'), CHAR_LENGTH('आ'),
       "as ascii", ascii('1'), LEN('1'), OCTET_LENGTH('1'), CHAR_LENGTH('1'),
       "as varchar(1)", ascii(col1), LEN(col1), OCTET_LENGTH(col1), CHAR_LENGTH(col1),
       "as char(1)", ascii(col2), LEN(col2), OCTET_LENGTH(col2), CHAR_LENGTH(col2),
       "as char(5)", ascii(col3), LEN(col3), OCTET_LENGTH(col3), CHAR_LENGTH(col3)
from t2
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38065433
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
victor16Выбегалло ... select ascii(col1), ascii(col2), ascii(col3) from t2 ...

А что, если вызвать функции LENGTH (also known as LEN), OCTET_LENGTH, CHAR_LENGTH (also known as CHARACTER_LENGTH)
Интересно, что они возвращают при установленном SQL_LOGICAL_CHAR ?

Nope.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
create table t1 (char(1));
create table t2 (col1 int);

create procedure save_length (p INT);
insert into t2 values (p);
return;
end procedure;

create trigger tr_t1 insert on t1  referencing  new as new_tab
    for each row
    (
    execute procedure save_length  (octet_length(new_tab.col1))
    );

insert into t1 values ("й");
select * from t2;
select * from t1;

       col1

          1

col1


-----------
truncate table t1;
truncate table t2;
alter table t1 modify (col1 char(4));
insert into t1 values ("й");
select * from t2;
select * from t1


       col1

          4


col1

й



Все так же преобразовывает в пробел, пала...
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38065435
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
victor16ВыбегаллоКонфигурационный параметр SQL_LOGICAL_CHAR ... че-то он у меня так и не заработал.

У меня работает, только если он был установлен при создании базы. Если установить SQL_LOGICAL_CHAR после создания базы, не оказывает никакого влияния, как будто его нет.

Ниже Ваш SQL-скрипт, немного подправленный:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
drop table if exists t2;
create table t2 (col1 varchar(1),
col2 char(1),
col3 char(5)
);

insert into t2 (col1, col2, col3) values ('आ', 'आ', 'आ' );
insert into t2 (col1, col2, col3) values ('1', '1', '1' );

select col1, col2, col3, 
       "as utf8", ascii('आ'), LEN('आ'), OCTET_LENGTH('आ'), CHAR_LENGTH('आ'),
       "as ascii", ascii('1'), LEN('1'), OCTET_LENGTH('1'), CHAR_LENGTH('1'),
       "as varchar(1)", ascii(col1), LEN(col1), OCTET_LENGTH(col1), CHAR_LENGTH(col1),
       "as char(1)", ascii(col2), LEN(col2), OCTET_LENGTH(col2), CHAR_LENGTH(col2),
       "as char(5)", ascii(col3), LEN(col3), OCTET_LENGTH(col3), CHAR_LENGTH(col3)
from t2



Из результатов видно, что длины значений UTF8 и ASCII при установленном SQL_LOGICAL_CHAR=4 различаются.
Для читабельности оформил в виде таблицы:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
SQL_LOGICAL_CHAR=OFF								
	UTF8 value				ASCII value			
col1						1			
col2						1			
col3	आ					1			
		ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH	ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH
as symbol	8824032	3	3		1		49	1	1		1
as varchar(1)	32	0	1		1		49	1	1		1
as char(1)	32	0	1		1		49	1	1		1
as char(5)	8824032	3	5		3		49	1	5		5

SQL_LOGICAL_CHAR=4								
	UTF8 value				ASCII value			
col1	आ					1			
col2	आ					1			
col3	आ					1			
		ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH	ASCII	LEN	OCTET_LENGTH	CHAR_LENGTH
as symbol	8824032	3	3		1		49	1	1		1
as varchar(1)	8824032	3	3		1		49	1	1		1
as char(1)	8824032	3	3		1		49	1	3		3
as char(5)	8824032	3	15		13		49	1	15		15


И как выглядит вывод dbschema -d .... -t t2 ?
...
Рейтинг: 0 / 0
Как ограничить вводимые данные латинскими символами ?
    #38065526
victor16
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Выбегалло И как выглядит вывод dbschema -d .... -t t2 ?

Разница как и ожидалось только в одном, rowsize при установленном SQL_LOGICAL_CHAR равно 22, без него 8.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Informix [игнор отключен] [закрыт для гостей] / Как ограничить вводимые данные латинскими символами ?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]