SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 06.04.2011 21:00:24

alxm
Участник
Зарегистрирован: 05.04.2011
Сообщений: 5

Строки размером больше 256KB

Имеется БД ”test”

Таблица  с единственным текстовым полем создается запросом:

drop table if exists tbl0;
create table tbl0 (fld0 longtext);

Есть код, создающий записи таблицы и заполняющий текстовое поле строкой увеличивающегося размера. Строки размером <=256KB создаются нормально, а выше этого предела выдается
ERROR: Incorrect arguments to mysqld_stmt_execute (MySQL error code: 1210, SQLState: HY000)
Не пойму, чем не нравится эта строка.

#include <string>
#include <stdio.h>

#include <cppconn/driver.h>
#include <cppconn/connection.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/exception.h>

using namespace std;
using namespace sql;

int main()
{
  Driver *drv;
  Connection *con;
  PreparedStatement * pst;

  try
  {
    drv = get_driver_instance();
    con = drv->connect("tcp://127.0.0.1:3306", "root", "1");
    con->setSchema("test");

    // aaa.length() = 256KB
    string aaa,bbb; int i;
    aaa = bbb = "0123456789abcdef"; for(i=0;i<14;i++){aaa.append(bbb);bbb=aaa;}
    // bbb.length() = 1B
    bbb = "0";

    pst = con->prepareStatement("INSERT INTO tbl0 (fld0) VALUES (?)");
    for(; 1; aaa.append(bbb) )
    {
      cout << aaa.length() << endl;
      pst->setString( 1, aaa );
      pst->executeUpdate();
    }
    delete pst;
    con->close();
    delete con;
  }
  catch (SQLException &e)
  {
    cout << "ERROR: SQLException in " << __FILE__;
    cout << " (" << __func__<< ") on line " << __LINE__ << endl;
    cout << "ERROR: " << e.what();
    cout << " (MySQL error code: " << e.getErrorCode();
    cout << ", SQLState: " << e.getSQLState() << ")" << endl;
    return EXIT_FAILURE;
  }
  catch (std::runtime_error &e)
  {
    cout << "ERROR: runtime_error in " << __FILE__;
    cout << " (" << __func__ << ") on line " << __LINE__ << endl;
    cout << "ERROR: " << e.what() << endl;
    return EXIT_FAILURE;
  }

  return EXIT_SUCCESS;
}

Неактивен

 

#2 08.04.2011 21:50:13

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Строки размером больше 256KB

Смотрите на ограничения размера пакета в Вашем приложении и в настройках
сервера MySQL (max_allowed_packet). Ну и убедитесь, что Ваш драйвер пра-
вильно обрабатывает такие запросы (например, попробуйте скормить строку
в 512к без параметров — просто большой длинный запрос).

Неактивен

 

#3 10.04.2011 22:45:33

alxm
Участник
Зарегистрирован: 05.04.2011
Сообщений: 5

Re: Строки размером больше 256KB

paulus, спасибо за ответ.

Настройки сервера позволяют осуществлять запросы размером до 16МБ, что для моих задач достаточно.:

$ mysqld --verbose --help | grep max_allowed_packet
max_allowed_packet 16777216

Возможность обрабоки запросов размером до 16MB подтверждена кодом:

string q="INSERT INTO tbl0 set fld0=\""+aaa+"\"";
Statement *stt = con->createStatement();

cout << q.length() << endl;
stt->execute(q);

Но я не смог выполнить эту часть задачи:

paulus написал:

Смотрите на ограничения размера пакета в Вашем приложении

Подскажите пожалуйста, где это можно посмотреть?

Неактивен

 

#4 11.04.2011 01:41:26

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Строки размером больше 256KB

Если пакеты 16 мегабайт нормально отправляются и принимаются (Ваш пункт 2),
то и пункт 3 Вы уже проверили.

Какой драйвер Вы используете для работы с MySQL? Я в mysql++ не могу повторить sad

#include <iostream>
#include <mysql++.h>

int main (int argc, char* argv[])
{
    using namespace mysqlpp;
    using namespace std;

    string s = "01234567890ABCDEF";
    for (int i = 0; i < 16; ++i) s = s + s;
    cout << "Length: " << s.length() << endl;

    Connection conn("mysql", "localhost", "root", "");
    Query query = conn.query();

    query << "INSERT INTO test.tbl (fld) VALUES (\"" << s << "\")";
    cout << "Exec: " << query.exec() << endl;
}


Код:

silentia:~/tmp$ g++ a.cc -I /usr/include/mysql++ -I /usr/include/mysql -lmysqlpp && ./a.out
Length: 1114112
Exec: 1
silentia:~/tmp$ mysql -e "SELECT LENGTH(fld) FROM tbl" test
+-------------+
| LENGTH(fld) |
+-------------+
|     1114112 |
+-------------+

Неактивен

 

#5 11.04.2011 02:16:04

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Строки размером больше 256KB

Ок, я ступил по поводу коннектора, моя вина smile

Но даже в этом коннекторе всё работает:

#include <iostream>
#include <cppconn/driver.h>
#include <cppconn/connection.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
#include <cppconn/exception.h>

int main (int argc, char* argv[])
{
    using namespace sql;
    using namespace std;

    Driver *drv = get_driver_instance();
    Connection *con = drv->connect("tcp://127.0.0.1:3306", "root", "");
    con->setSchema("test");

    string s = "01234567890ABCDEF";
    for (int i = 0; i < 16; ++i) s = s + s;
    cout << "Length: " << s.length() << endl;

    PreparedStatement *pst = con->prepareStatement("INSERT INTO tbl (fld) VALUES (?)");
    pst->setString(1, s);
    pst->executeUpdate();
   
    delete pst;
    con->close();
    delete con;
}


Ждать, когда наберется 256к по 1 байтику, не стал, простите. Можете проверить,
ошибка начинается при накоплении, или сразу на 256к ломается?

Неактивен

 

#6 11.04.2011 08:56:51

alxm
Участник
Зарегистрирован: 05.04.2011
Сообщений: 5

Re: Строки размером больше 256KB

По байтику я бы тоже не стал прибавлять, если бы в нужном мне диапазоне все работало. Но сейчас, добавляя байтики, перепроверил. Как и указал в первом посте, при длинне параметра <=262144 запрос обрабатывается без ошибок. А при длинне >=262145 выдает ошибку "Incorrect arguments to mysqld_stmt_execute".

Неактивен

 

#7 11.04.2011 18:06:22

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Строки размером больше 256KB

А мой тест попробуйте скомпилировать? Там чуть больше мегабайта.

Неактивен

 

#8 11.04.2011 18:17:50

alxm
Участник
Зарегистрирован: 05.04.2011
Сообщений: 5

Re: Строки размером больше 256KB

Результат:

Length: 1114112
terminate called after throwing an instance of 'sql::SQLException'
  what():  Incorrect arguments to mysqld_stmt_execute
Aborted

Неактивен

 

#9 11.04.2011 18:24:43

alxm
Участник
Зарегистрирован: 05.04.2011
Сообщений: 5

Re: Строки размером больше 256KB

И с ограничением размера:

    s = s.substr(0,262144);
    cout << "Length: " << s.length() << endl;

    PreparedStatement *pst = con->prepareStatement("INSERT INTO tbl0 (fld0) VALUES (?)");
    pst->setString(1, s);
    pst->executeUpdate();

Length: 262144

    s = s.substr(0,262145);
    cout << "Length: " << s.length() << endl;

    PreparedStatement *pst = con->prepareStatement("INSERT INTO tbl0 (fld0) VALUES (?)");
    pst->setString(1, s);
    pst->executeUpdate();

Length: 262145
terminate called after throwing an instance of 'sql::SQLException'
  what():  Incorrect arguments to mysqld_stmt_execute
Aborted

Отредактированно alxm (11.04.2011 18:25:19)

Неактивен

 

#10 12.04.2011 16:27:37

deadka
Администратор
Зарегистрирован: 14.11.2007
Сообщений: 2422

Re: Строки размером больше 256KB

Мерзкий глюк sad. И размер ведь отнюдь не зашкаливающий...
Этот коннектор - это же ведь разработка самих mysql-щиков? Пробовали на bugs.mysql.com постить?


Зеленый свет для слабаков, долги отдают только трусы, тру гики работают только в консоли...

Неактивен

 

#11 12.04.2011 21:02:50

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Строки размером больше 256KB

Не, это не бага коннектора. У меня же всё работает. Какая ОС, какой коннектор?
Пробовали собирать коннектор вручную?

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson