|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Привет всем. Суть вопроса в том, что при наличии в поле типа VARCHAR символа с нулевым кодом функция CHAR_LENGTH() возвращает полную длину с у четом символов после #0, а собственно значение поля возвращается обрезанным до первого нулевого символа. Ниже приведен несложный сценарий для ISQL: CREATE TABLE ITEMS ( ID INTEGER NOT NULL, NAME VARCHAR(100) NOT NULL ); ALTER TABLE ITEMS ADD CONSTRAINT PK_ITEMS PRIMARY KEY (ID); ALTER TABLE ITEMS ADD CONSTRAINT UNQ_ITEMS UNIQUE (NAME); INSERT INTO ITEMS( ID, NAME ) VALUES ( 1, 'Name #1' ); COMMIT; SELECT '<' || NAME || '>', CHAR_LENGTH( NAME ) FROM ITEMS; /* Здесь все правильно, символа #0 нет */ NAME CHAR_LENGTH ============================================= <Name #1> 7 /* добавляем нулевой символ */ UPDATE ITEMS SET NAME = NAME || ASCII_CHAR( 0 ) || '+++'; SELECT '<' || NAME || '>', CHAR_LENGTH( NAME ) FROM ITEMS; /* Ошибка: CHAR_LENGTH() возвращает большее значение, нежели чем собственно возвращенное значение поля NAME возвращенное значение поля NAME обрезано до первого нулевого символа */ NAME CHAR_LENGTH ============================================= <Name #1 11 /* повторно добавляем нулевой символ */ UPDATE ITEMS SET NAME = NAME || ASCII_CHAR( 0 ) || '+++'; SELECT '<' || NAME || '>', CHAR_LENGTH( NAME ) FROM ITEMS; /* значение, возвращенное функцией CHAR_LENGTH(), увеличилось на 4 возвращенное значение поля NAME не изменилось (так же обрезано до первого нулевого символа ) */ NAME CHAR_LENGTH ============================================= <Name #1 15 С уважением, Polesov. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 15:36 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Polesov Код: sql 1.
Во всех остальных чарсетах нулевой символ не является валидным и последствия его вставки неопределены. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 15:44 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Тестировалось на CHARACTER SET WIN1251 Но ведь функция CHAR_LENGTH() возвращает значение с учетом того, что находится за нулевым символом. И при передаче параметра в UDF BY DESCRIPTOR значение поля dsc_length структуры, описывающей параметр, тоже содержит значение с учетом того, что находится за нулевым символом. Все же, если значение поля выводится до первого попавшегося нулевого символа, то и результат функции CHAR_LENGTH() тоже должен учитывать наличие нуля, а не брать значение фактической длины хранящихся в БД данных. С уважением, Polesov. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 15:59 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Вдогонку: SELECT CHAR_LENGTH( '123' || ASCII_CHAR( 0 ) || '321' ) FROM RDB$DATABASE; возвращает 7 ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 16:05 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Polesovесли значение поля выводится до первого попавшегося нулевого символа, то... ....это происходит исключительно в силу того, что в С строки традиционно null-terminated. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 16:39 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Ну, тогда надо, чтобы в FB функция CHAR_LENGTH() тоже возвращала результат согласно лучшим традициям С ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 17:27 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Polesovтогда надо Кому и зачем? Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 17:31 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov....это происходит исключительно в силу того, что в С строки традиционно null-terminated. У меня с нулём возвращает, на Delphi. Пропатчил UIB чтобы нормально с октетами работал. А ваш репликатор разве обрезает такие строки? ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 17:37 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
-А ваш репликатор разве обрезает такие строки? Мой репликатор не использует ни CHAR_LENGTH(), ни вывод данных на экран. И таки нет, с такими странными строками при репликации ничего не происходит, поскольку любые данные рассматриваются как двоичные и (в общем случае) не подвергаются никакому преобразованию, передаваясь "как есть". Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 18:07 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov, По крайней мере, при передаче в UDF параметра типа CSTRING BY DESCRIPTOR, значение dsc_length в структуре описания этого параметра содержит такое же значение, как и результат функции CHAR_LENGTH(), т.е. без учета нулевого символа. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 18:19 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
насколько я понимаю, ошибка именно в выводе ISQL на экран. Сам по себе нулевой байт в середине строки хоть и заноза в заднице, но абсолютно валиден. ... |
|||
:
Нравится:
Не нравится:
|
|||
22.05.2015, 19:13 |
|
FB2.5 - VARCHAR, содержащие ASCII_CHAR( 0 )
|
|||
---|---|---|---|
#18+
Привет всем. Ниже пояснения по старттопику. Вводная: Имеются внешние текстовые данные, которые по связке с неким критерием заносятся в базу через хранимую процедуру. Соответственно, в связке с этим неким критерием возможны следующие ситуации: - внешние данные отсутствуют: при этом в БД пишется NULL; - внешние данные содержат пустую стоку: при этом в БД пишется пустая строка; - внешние данные введены: при этом в БД пишется строка, обработанная некой UDF. Объявление UDF: Код: plsql 1. 2. 3. 4.
Естественно, при наличии во входной строке нулевого символа происходила потеря данных. Решение проблемы – реализация передачи входного параметра типом VARCHAR BY DESCRIPTOR: Код: plsql 1. 2. 3. 4. 5.
Структура описания параметра: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8.
Для типа VARCHAR dsc_address в первых 2-х байтах содержит такое же значение, как и результат функции CHAR_LENGTH(), т.е. реальную длину без учета нулевых символов. При этом надо, что бы входная строка передавалась именно типом VARCHAR (dsc_dtype = 3), что обеспечивается преобразованием Код: plsql 1.
Кстати, при таком решении логику на равенство параметра пустому значению или на IS NULL можно перенести в саму UDF. Данные для просмотра строк с нулевым символом можно вытаскивать через Код: plsql 1.
С уважением, Polesov. ... |
|||
:
Нравится:
Не нравится:
|
|||
23.05.2015, 17:05 |
|
|
start [/forum/topic.php?fid=40&fpage=76&tid=1562834]: |
0ms |
get settings: |
11ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
26ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
57ms |
get tp. blocked users: |
2ms |
others: | 274ms |
total: | 406ms |
0 / 0 |