Подготовленные утверждения поддерживаются во встроенных MySQL
Обычно я разрабатываю сервер с живыми, но в первый раз я решил, что сделаю прыжок и посмотрю, смогу ли я получить весь мой (С++) код mysql, работающий как встроенный сервер. В частности, я очень увлекаюсь подготовленными заявлениями, как они есть (ИМХО) "в целом", превосходящими неподготовленный сорт.
Я пробовал использовать libmysqld из 5.5.22 и libmysqld из 5.6.4 и не работал.
Соединение выполнено, простые команды mysql_query/mysql_real_query работают нормально, но как только мой первый подготовленный оператор выдает mysql_stmt_fetch(), я получаю ошибку "команды из синхронизации".
Очень похожая проблема появилась на форумах oracles (http://forums.mysql.com/read.php?168,507863,507863#msg-507863) без разрешения.
Я не вижу и не считаю, что мне не хватает команд между mysql_real_connect() и mysql_stmt_fetch().
Все мои поиски оказались пустыми для любого примера встроенного сервера, который использует подготовленные операторы. Я также не нашел фактическое предложение "вы не можете этого сделать".
Итак... это или не поддерживается?
Спасибо за ваш опыт.
//редактировать
чтобы деактивировать это дальше (и при необходимости инструктировать) моя полная последовательность mysql cmd выглядит следующим образом:
mysql_library_init(); // as embedded
mysql_init();
mysql_options(MYSQL_SET_CHARSET_NAME); //to utf8
mysql_options(MYSQL_OPT_USE_EMBEDDED_CONNECTION);
mysql_real_connect();
mysql_real_query("SET NAMES 'utf8'");
mysql_real_query("SET CHARACTER SET 'utf8'");
mysql_set_character_set("utf8"); // yes, you really do need to set utf8 four times
mysql_autocommit( mAutocommit );
в этот момент mysql_real_query() вызывает DO. Я продолжаю...
//all this would only happen once for each stmt
{
mysql_stmt_init();
mysql_stmt_prepare(theQuery);
mysql_stmt_param_count(); // to assert input bind object (aka the predicates) has the same number of params as theQuery
mysql_stmt_result_metadata()
mysql_num_fields(); // to assert the output bind object has the same number of params as theQuery
mysql_free_result(metadata);
mysql_stmt_bind_param(); // called IF there are input params
mysql_stmt_bind_result(); // pretty much always called for the output params
}
// and at last
mysql_stmt_execute();
//mysql_stmt_store_result(); //{OPTIONAL: use if you want to buffer the fetch - I dont}
mysql_stmt_fetch(); // ERROR! commands out of sync.
// and for completeness,
mysql_stmt_free_result();
mysql_stmt_close();
// and the shutdown
mysql_close();
mysql_library_end();
Ответы
Ответ 1
Я боялся этого.. но после небольшой работы я получил ответ на свой вопрос и решение проблемы. (да, я ленивый кодер... я бы надеялся, что кто-то еще сказал бы мне, что все это необходимо.)
Вот мой собственный авторитетный ответ на встроенный сервер + подготовленные заявления, не работающие на вопрос.
вопрос: поддерживаются ли stmts во встроенных? ответ... они должны быть, но они НЕ.
Да, во встроенном mysql есть ошибка в отношении stmts. Видеть:
http://bugs.mysql.com/bug.php?id=62136
Г-н Ци Чжоу имеет все мое уважение. Он каким-то образом определил, что при запуске embedded mysql_stmt_execute() неправильно установил статус результата на "MYSQL_STATUS_GET_RESULT" вместо "MYSQL_STATUS_STATEMENT_GET_RESULT" (то есть обрабатывал stmt как не-статут). Это, очевидно, естественно приводило к "командам из синхронизации", ошибка. Поэтому он требует исправления самого исходного кода.
Как это сделать..
Страница MySql "как построить на окнах" здесь: http://dev.mysql.com/doc/refman/5.5/en/source-installation.html
ссылается на это гораздо проще для чтения, КАК-СТРОИТЬ:
http://www.chriscalender.com/?p=689
Дополнительные примечания HOW-TO, которые я определил в процессе
Крис, как это сделать для VS2008 express. Я использую 2010 Pro и узнал, что cmake -G arg может быть опущен. Для меня 2010 был авто-определителем, который должен использоваться компилятором.
Я установил только cmake и bison. perl и bazaar для этого не требуются. и я получил стандартный исходный дистрибутив 5.5.22 вместо того, чтобы вытащить из базара.
re: установка бизона:
- Обязательно установите бизон на путь без пробелов.
- НЕ разрешайте установщику добавлять что-либо в меню "Пуск" (вызвано "m4.exe not
найденная "ошибка)
- вручную добавьте папку bison bin в систему PATH
re: signtool.exe
убедитесь, что путь к signtool добавлен в PATH. Пример (для меня)
- c:\Program Files\Microsoft SDK\Windows\v7.0A\bin
Загрузите исходный дистрибутив MySql (http://dev.mysql.com/downloads/mysql/#downloads):
Общий Linux (независимая архитектура), сжатый архив TAR (mysql-5.5.22.tar.gz)
Вам нужно отредактировать {D:\your_path}\mysql-5.5.22\libmysqld\lib_sql.cc
В строке 340 вы увидите:
if (res)
{
NET *net= &stmt->mysql->net;
set_stmt_errmsg(stmt, net);
DBUG_RETURN(1);
}
//ADD CODE HERE
DBUG_RETURN(0);
Вставьте между блоком if и DBUG_RETURN (0) следующее:
//kgk 2012/04/11 - see http://bugs.mysql.com/bug.php?id=62136
// Qi Zhou modification to allow prep'd stmts to work
else if (stmt->mysql->status == MYSQL_STATUS_GET_RESULT)
{
stmt->mysql->status= MYSQL_STATUS_STATEMENT_GET_RESULT;
}
Создайте новую версию libmysqld.dll, libmysqld.lib, libmysqld.pdb
и проблема исправлена.
Когда вы построили dll, не делайте, как я, и забудьте переместить новую DLL в свою двоичную папку времени выполнения и сидеть там, задаваясь вопросом, почему это изменение ничего не делало. Вздох.
FYI: комментарий об ошибке оракула techie с тегом [20 Feb 18:34] Света Смирнова
является полной неузнаваемостью. serverARgs ничего не имеет к делу.
Ответ 2
http://dev.mysql.com/doc/refman/5.1/en/mysql-stmt-execute.html
Извините за мой плохой английский, но проблема в том, что mysql_stmt_fetch открывает курсор, но mysql_stmt_execute выполняет только туза mysql_stmt_store_result с помощью курсора...
Ответ 3
Встроенный MySQL - это тот, который обычно не используется, и для этой проблемы я много раз искал веб-сайт, и я подготовил отдельный проект. При этом я многому научился, и одним из них является то, что сначала выполнить запрос, а затем сохранить результаты.
Чтобы избавиться от различных типов запросов, любезно создайте объект для выполнения и верните результат, и в этом случае вам не нужно снова и снова выполнять запрос выполнения.
В данном случае пользователь не выполнил запрос и попытался сохранить результаты, и это происходит только при попытке скопировать другие команды. Таким образом, решение проблемы состоит в выполнении mysql_stmt_execute
, а затем вызов mysql_stmt_store_result