DATALENGTH SQL функция для (UTF-8) ТЕКСТ в Sqlite? - PullRequest
0 голосов
/ 07 апреля 2020

Я использую интерфейс C для SQLite, и мне нужно указать размер строки, хранящейся в столбце TEXT, то есть то, что некоторые базы данных будут поддерживать с использованием

SELECT DATALENGTH(body) FROM table;

Однако SQLite не имеет функции DATALENGTH. Поскольку рассматриваемый текст довольно большой, я хочу избежать загрузки фактического столбца body с диска. Поскольку TEXT - это utf8, LENGTH(body) не возвращает желаемый результат (он возвращает количество символов, тогда как мне нужно знать размер хранилища). Преобразование столбца в BLOB не вариант, поскольку база данных создается сторонней программой.

Q: Есть ли способ получить эту информацию непосредственно из базы данных, если не считать пользовательскую SQL функцию ? Файл в формате SQLite хранит длину полей TEXT, поэтому я буду удивлен, если эта информация действительно не будет раскрыта.

Связано:

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Приведение к BLOB-объекту для получения размера в байтах от length():

SELECT length(cast(body AS BLOB)) FROM table;
0 голосов
/ 07 апреля 2020

В отличие от ответа @ Shawn, оказывается, что реализация пользовательской функции SQL на самом деле довольно проста:

/* Implement the DATALENGTH() SQL function. Code adapted from the SQLite source
 * for the LENGTH() function.
 */
static void db_sqlite_datalength(sqlite3_context *context, int argc,
        sqlite3_value **argv)
{
    (void) argc;

    switch(sqlite3_value_type(argv[0])) {
    case SQLITE_BLOB:
    case SQLITE_INTEGER:
    case SQLITE_FLOAT:
    case SQLITE_TEXT:
        sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
        break;
    default:
        sqlite3_result_null(context);
        break;
    }
}

static int db_register_custom_functions(sqlite3 *db)
{
    return sqlite3_create_function(db, "datalength", 1,
            SQLITE_UTF8 | SQLITE_DETERMINISTIC, NULL,
            &db_sqlite_datalength, NULL, NULL);
}

Поскольку встроенная функция length реализована точно так же, производительность должно быть в порядке. Я немного просмотрел исходники sqlite3, но не так просто определить, когда именно происходит доступ к диску. Предположительно, sqlite3 mmap имеет все, что важно для производительности, - это то, что возможные переполнения страниц для длинных полей TEXT не требуются без необходимости.

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