Oracle возвращает неправильные значения с LENGTH и INSTR - PullRequest
0 голосов
/ 19 февраля 2020

Я собираюсь получить положение символов в строке плюс длину строки.

Значение поля notes в таблице internal_notes для строки с ticket_id равно 1679467247 буквально «это тестовая заметка».

Когда я использую функции против литералов, которые они работают, но когда я получаю информацию непосредственно из столбца таблицы, значения просто неверны .

Есть идеи о том, что может происходить?

select notes,
       LENGTH(notes),
       INSTR(notes,' ')
FROM   internal_notes
where  ticket_id = 1679467247

union

select 'this is a test note',
       LENGTH('this is a test note'),
       INSTR('this is a test note',' ')
from   dual

Возвращает следующее:

NOTES               LENGTH(NOTES) INSTR(NOTES,' ')
------------------- ------------- ----------------
this is a test note            32                11
this is a test note            19                5

1 Ответ

4 голосов
/ 19 февраля 2020

Вы можете получить это явное несоответствие, если в значении есть символы нулевой ширины; например:

create table internal_notes(ticket_id number, notes varchar2(32 char));
insert into internal_notes(ticket_id, notes)
values (1679467247, unistr('\200c\200cthis is a test note\200c\200c\200c\200c\200c\200c\200c\200c\200c\200c\200c'));
insert into internal_notes(ticket_id, notes)
values (1679467248, unistr('\200c\200cthis is a test note'));
insert into internal_notes(ticket_id, notes)
values (1679467249, 'this is a test note');

select notes,
       LENGTH(notes),
       INSTR(notes,' ')
FROM   internal_notes
where  ticket_id = 1679467247;

NOTES                            LENGTH(NOTES) INSTR(NOTES,'')
-------------------------------- ------------- ---------------
‌‌this is a test note‌‌‌‌‌‌‌‌‌‌‌                         32               7

Я сказал «явное несоответствие», потому что эти цифры верны; они просто не смотрят, если вы не видите некоторых персонажей. Невидимые символы по-прежнему считаются.

Как и @MTO, вы можете использовать функцию dump() , чтобы точно увидеть, что хранится в таблице, в десятичном или шестнадцатеричном представлении или смешано с 'normal 'символы, которые немного легче интерпретировать:

select notes,
       LENGTH(notes),
       INSTR(notes,' '),
       dump(notes, 1000) as dmp
FROM   internal_notes;

NOTES                            LENGTH(NOTES) INSTR(NOTES,'')
-------------------------------- ------------- ---------------
DMP                                                                                                                                                                   
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
‌‌this is a test note‌‌‌‌‌‌‌‌‌‌‌                         32               7 
Typ=1 Len=58: e2,80,8c,e2,80,8c,t,h,i,s, ,i,s, ,a, ,t,e,s,t, ,n,o,t,e,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,8c,e2,80,
8c                                                                                                                                                                    

‌‌this is a test note                         21               7 
Typ=1 Len=25: e2,80,8c,e2,80,8c,t,h,i,s, ,i,s, ,a, ,t,e,s,t, ,n,o,t,e                                                                                                 

this is a test note                         19               5 
Typ=1 Len=19: t,h,i,s, ,i,s, ,a, ,t,e,s,t, ,n,o,t,e                                                                                                                   

db <> fiddle - хотя это показывает символы нулевой ширины в виде вопросительных знаков, в отличие от SQL Developer и SQL* Плюс.

Доступны другие символы нулевой ширины ( пробел , без присоединения , присоединение ), и вы можете увидеть что-то другое в вашем дампе - это просто должно быть что-то, что ваш клиент вообще не отображает. Что бы там ни было, если это затрагивает все строки, а не только этот отдельный тикет, то как и почему, вероятно, зависит от того, какой интерфейс / приложение заполняет таблицу - возможно, из-за несоответствия набора символов, но это может быть преднамеренным. Если это просто билет, то эта записка - интересный тест ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...