Конференция "Базы" » TWideStringField.Size - некорректный размер [D2010]
 
  • Чемпаркароке © (02.08.17 14:15) [0]
    если использовать кодировку UTF8 и dbExpress, то Size дает ровно в 4 раза больше, чем есть на самом деле, хотя в справке сказано
    Size is the maximum number of characters in the string.
    т.е. именно символов, а не байтов
    если ж взять кодировку win1251, то размер правильный

    вопрос - это глюк драйвера или ошибка в документации?
    склоняюсь к первому, т.к. поля CHAR(1) вдруг на клиенте вырастают до 4 символов и дополняются пробелами

    у кого есть возможность, пожалуйста, проверьте в других версиях Delphi новее 2010
  • Чемпаркароке © (15.08.17 14:38) [1]
    судя по вопросам, которые я накопал в интернете по этому поводу, болячка старая и запущенная, появилась вместе с юникодом в BDS-2006
    за столько лет вполне могла стать фичей, хоть и недокументированной

    это проявляется не только в dbExpress, но и в ADO
    не имеет значения и кодировка в БД, важно, что указано в настройках коннекта к БД

    из всего этого можно сделать вывод, что драйвер тут вряд ли имеет значение, скорее, где-то во внутренностях компонентов доступа к данным недоработка
  • sniknik © (15.08.17 20:55) [2]
    > но и в ADO
    в ADO нет "внутренностей компонентов доступа к данным", это по сути внешний COM объект, в компонентах просто доступ через интерфейсы к ним.

    старая и запущенная болячка, она не компонентах, она в головах.
  • Чемпаркароке © (15.08.17 21:10) [3]

    > sniknik ©   (15.08.17 20:55) [2]

    значит, делаешь вывод, что описанное в сабже поведение - нормативное?
    или просто к словам цепляешься?
  • sniknik © (15.08.17 23:12) [4]
    я не делаю вывод, только факты.
    в сабже о dbExpress, ничего не знаю про dbExpress... практически не пользовался им. а написал про ADO про которое ты сделал вывод, явно не понимая принципов его работы.
  • Чемпаркароке © (20.08.17 13:54) [5]
    аналогичная ситуация и при работе через IBX
  • sniknik © (20.08.17 18:49) [6]
    ну, если это везде так, то видимо одинаково делают... (а чего бы отличатся?)
    хотя все одно, говорю только за ADO
    он не держит в рекордсете типов utf-8 и другое, только юникод и ansi (локализацию) типы описаны в разделе справки по обьектам ado в разделе DataTypeEnum ( https://docs.microsoft.com/en-us/sql/ado/reference/ado-api/datatypeenum ), ну мелкософт же, чего ему внутри себя с чужими кодировками работать? но это не значит, что не понимает их, в базе может быть в любой, главное правильно указать он/драйвер преобразует из любого имеющегося на машине/в разделе
    HKEY_CLASSES_ROOT\MIME\Database\Charset
    а вот данные "наружу" (при сохранении в файл/передачи в стриме) используется именно utf-8 ибо спецификация... т.е. нельзя сказать что они не умеют с ним работать, не хотят, ну я бы тоже не хотел учитывая все проблемы при работе в живую на транспортной кодировке.

    ты видать пытаешся работать с utf в ansi строках, он позволяет, ибо это его суть - универсальность на стандартных ansi кодах.
    а вот это
    > и дополняются пробелами
    указывает, что тип в базе char(), а не varchar(), это тоже его стандартное поведение дополнять пробелами до указанной в типе длинны, еще с dbase 3 повелось (ну может не 3 но смысл что "стандарт" со времен "царя гороха").
  • Чемпаркароке © (20.08.17 23:00) [7]

    > указывает, что тип в базе char(), а не varchar(), это тоже
    > его стандартное поведение дополнять пробелами до указанной в типе длинны,

    поведение верное, но не в данном случае
    как я уже сказал поля CHAR(1) вдруг на клиенте вырастают до 4 символов и дополняются пробелами
    т.е. в БД - 1 символ длина поля (а не содержимого), в на клиенте уже 4 символа
  • Чемпаркароке © (20.08.17 23:03) [8]
    т.е. по сути где-то ошибочно подменяется понятие длины поля в символах на длину поля в байтах (т.е. длину места в памяти), необходимых для хранения этих символов
  • Чемпаркароке © (20.08.17 23:04) [9]
    а для длины в байтах есть отдельное свойство DataSize
  • rrrrrrr © (21.08.17 10:03) [10]
    открываешь исходники.

    смотришь, что сайз объявлен у TField и ссылается на гетсайз который возвращает fSize

    У стрингфилд он перенесен в паблишед и никаких доп телодвижений не наблюдается

    вайдстрингфилд наследован от тстрингфилд

    и тоже никакой особой обработки вокруг размера не имеет.

    а размерность полей tfield узнает у  клиентских библиотек сервера.

    итого на весь этот захватывающий детектив ушло полторы минуты рассматривания db.pas
  • sniknik © (21.08.17 10:16) [11]
    > т.е. по сути где-то ошибочно подменяется понятие длины поля в символах на длину поля в байтах
    да, у тебя в голове. суть utf-8:
    > ибо это его суть - универсальность на стандартных ansi кодах.
    т.е. впихивая utf-8 в поле с типом ansi ты просто говоришь ему - это строка символов, обычных. т.к. нет разницы между обычными символами и utf-8, кроме как в интерпретации (договоренности, вот это вот считать utf-8, а это ansi, ну может исключая файлы, там еще определяется BOM, если он есть).
  • sniknik © (21.08.17 10:39) [12]
    > т.е. в БД - 1 символ длина поля (а не содержимого), в на клиенте уже 4 символа
    вообще это неправда... опять ты что то не так интерпретировал. если в базе длинна поля 1 символ для типа utf-8, то она должна быть равна 7 простых символов/байт, а не 4ре. т.к. длинна символов utf-8 переменная от 1го до 7ми (вроде, не охота вникать, как помню, может 8, но точно не 4). в четыре некоторые не влезут в общем, что приведет к ошибкам в базе... что в общем вряд ли, т.к. базы делают обычно грамотные разработчики.
  • Игорь Шевченко © (21.08.17 12:14) [13]
    sniknik ©   (21.08.17 10:39) [12]

    Я тебе открою страшный секрет - при использовании юникодной базы данных Oracle (UTF-8) размер символьного поля в неюникодной версии Delphi получается в 4 раза больше, чем объявленная длина поля в базе данных.
    И никому это не мешает.

    Базы делают грамотные разработчики, Delphi пишут тоже грамотные разработчики.
  • sniknik © (21.08.17 13:53) [14]
    может тогда все таки внутреннее представление он держит в UTF-32?
    или UTF-16, тоже возможно тут либо одно либо 2 слова на символ. а уже наружу отдает так как программист поле указал...

    > И никому это не мешает.
    сохрани туда и прочитай обратно какой нибудь семибайтный символ UTF-8. не мешает? тогда как?
  • rrrrrrr © (21.08.17 14:01) [15]
    как он внутренне складирует это отдельный вопрос. как сказали при установке.
    а отдает так как попросишь.
  • sniknik © (21.08.17 14:01) [16]
    а, понял, посмотрел
    https://ru.wikipedia.org/wiki/UTF-8
    5 и 6 байтные уже не имеют представления в юникоде
    00200000 — 03FFFFFF  5 байт  не используется в Unicode
    04000000 — 7FFFFFFF  6 байт  не используется в Unicode

    т.е. нет смысла больше размерность делать. просто UTF-8 позволяет до 7ми, а символов под это нет...
  • sniknik © (21.08.17 14:04) [17]
    > а отдает так как попросишь.
    не только в этом вопрос, это как раз очевидно, еще и в том что компонент делфи для такого поля выделяет 4 байта, хотя казалось бы должен 7. но тут может и есть не тоже самое, я ошибся когда подумал, что должно выделять под полный символ.
  • Чемпаркароке © (22.08.17 14:30) [18]

    > а размерность полей tfield узнает у  клиентских библиотек сервера.

    верно, но вопрос, как он интерпретирует то, что получил
    особенно, если по пути есть еще драйвер-посредник
  • rrrrrrr © (22.08.17 14:43) [19]
    заняться ему больше нечем как интерпретацией прямого ответа какого размера поле ему сейчас прилетит.
 
Конференция "Базы" » TWideStringField.Size - некорректный размер [D2010]
Есть новые Нет новых   [134427   +34][b:0][p:0.001]