2012-03-29 18 views
17

Normalmente desarrollo con un servidor en vivo, pero por primera vez pensé que daría el salto y vería si pudiera obtener todo mi código mysql (C++) funcionando como servidor incrustado. Particularmente, soy muy aficionado a las declaraciones preparadas ya que son (en mi humilde opinión) "en general" superiores a la variedad no preparada.Son declaraciones preparadas compatibles con MySQL incorporado

He intentado usar libmysqld desde 5.5.22 y libmysqld desde 5.6.4 y ninguno funciona.

La conexión está hecha, los comandos simples mysql_query/mysql_real_query funcionan bien, pero tan pronto como mi primera declaración preparada emita un mysql_stmt_fetch() obtengo el odiado error de 'comandos no sincronizados'.

Un problema similar aparece en los foros de oráculos (http://forums.mysql.com/read.php?168,507863,507863#msg-507863) sin resolución.

No veo, ni creo que me falten comandos entre mysql_real_connect() y mysql_stmt_fetch().

Todas mis búsquedas han quedado vacías para cualquier ejemplo de un servidor incrustado que esté utilizando declaraciones preparadas. Tampoco he encontrado una oración real "no puedes hacer esto".

Entonces ... ¿es o no es compatible?

Gracias por su experiencia.

// editar fin de desmitificar esta otra (y si es necesario instruir a) mi secuencia de MySQL cmd completa es la siguiente:

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); 

en este punto, mysql_real_query() llama a hacer el trabajo. Sigo ...

//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(); 

Respuesta

3

Tenía miedo de esto ... pero después de no poca cantidad de trabajo, tengo una respuesta a mi pregunta y una solución al problema. (Sí, soy un codificador perezoso ... esperaba que alguien más me hubiera dicho todo esto era necesario ...)

Aquí está mi propia respuesta autorizada al servidor incrustado + declaraciones preparadas que no funcionan.

la pregunta: ¿se admiten stmts en embedded? la respuesta ... deberían ser, pero NO lo son.

Sí, hay un error en mysql incrustado con respecto a stmts. Ver: http://bugs.mysql.com/bug.php?id=62136

Mr Qi Zhou tiene todo mi respeto. De alguna manera determinó que al ejecutar incrustado, mysql_stmt_execute() establecía incorrectamente el estado del resultado en "MYSQL_STATUS_GET_RESULT" en lugar de "MYSQL_STATUS_STATEMENT_GET_RESULT" (es decir, tratar una stmt como no declarada) Esto, obviamente, conduciría naturalmente a un "comando fuera de sincronización" error. Por lo tanto, requiere parchear el código fuente en sí.

Cómo hacer eso .. El MySQL "cómo construir en las ventanas" página aquí: http://dev.mysql.com/doc/refman/5.5/en/source-installation.html

referencias esto mucho más fácil de leer, cómo-a-BUILD: http://www.chriscalender.com/?p=689

Notas adicionales HOW-TO que determiné en el proceso

El manual de Chris es para VS2008 express. Uso 2010 Pro y aprendí que el cmake -G arg puede ser omitido. Para mí, 2010 fue autodeterminado para ser el compilador a usar.

Solo instalé cmake y bison. perl y bazar no son necesarios para esto. y obtuve la distribución de fuente estándar 5.5.22 en lugar de sacar del bazar.

re: la instalación de bisontes:

  • asegúrese de instalar el bisonte a una ruta sin espacios
  • NO permita instalador añade nada al menú de inicio (hizo que el "m4.exe no encontrado" error)
  • añadir manualmente la carpeta del compartimiento de bisontes a la ruta del sistema

re: signtool.exe

asegúrate de que la ruta de acceso a signtool se haya agregado a PATH. Ejemplo (para mí)

  • c: \ Archivos de programa \ Microsoft SDKs \ Windows \ v7.0A \ bin

descargar la distro fuente de MySQL (http://dev.mysql.com/downloads/mysql/#downloads): Linux genérico (Arquitectura Independiente) , comprimido archivo TAR (mysql-5.5.22.tar.gz)

Hay que editar {D: \ your_path} \ mysql-5.5.22 \ libmysqld \ lib_sql.cc

en la línea 340 se quiere ver:

if (res) 
{ 
    NET *net= &stmt->mysql->net; 
    set_stmt_errmsg(stmt, net); 
    DBUG_RETURN(1); 
} 
//ADD CODE HERE 
DBUG_RETURN(0); 

de inserción entre el bloque de código si y DBUG_RETURN (0) lo siguiente:

//kgk 2012/04/11 - see http://bugs.mysql.com/bug.php?id=62136 
// Qi Zhou's 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; 
} 

Y elaborar una nueva versión de lanzamiento de libmysqld.dll, libmysqld.lib, libmysqld.pdb

y el problema esta arreglado

Cuando haya creado el dll, no haga como yo y olvide mover la nueva DLL a la carpeta de tiempo de ejecución de su binario y siéntese preguntándose por qué el cambio no hizo nada. Suspiro.

FYI: error de techie de oracle informe de informe etiquetado con [20 Feb 18:34] Sveta Smirnova es nonesense completo. el serverARgs no tiene nada que ver con nada.

-2

Embedded MySQL es la que normalmente no se utilizo para este problema y he buscado los lotes web de veces y he preparado un proyecto separado. Al hacerlo, he aprendido muchas cosas y una de ellas es que primero ejecute la consulta y luego almacene los resultados.

Para deshacerse de diferentes tipos de consultas amablemente crea un objeto para la ejecución y devuelve el resultado y en este caso no tienes que escribir la consulta de ejecución una y otra vez.

En el presente caso, el usuario tampoco ejecutó la consulta e intentó almacenar los resultados, y esto solo ocurre cuando intenta copiar otros comandos. Así, la solución al problema es ejecutar mysql_stmt_execute y luego llamar mysql_stmt_store_result

+1

Gracias por su ayuda. Mi pregunta no es sobre el valor de las declaraciones preparadas, sino sobre la información relacionada con el hecho de que funcionen o no con la biblioteca mysql incorporada (es decir, sin servidor externo). Para mí, NO están funcionando. en segundo lugar, llamar a mysql_stmt_store_result no es relevante. Para su referencia, vea: http://dev.mysql.com/doc/refman/5.5/en/mysql-stmt-store-result.html si no está almacenando en búfer la búsqueda (que NO), entonces NO Necesito llamar a la tienda (que no). Sin embargo, solo para ver, probé su sugerencia y la desincronización se produce en el comando de la tienda. –

-1

http://dev.mysql.com/doc/refman/5.1/en/mysql-stmt-execute.html

siento por mi mala Inglés, pero el problema es que mysql_stmt_fetch cursor abierto, pero sólo se ejecutará el trabajo mysql_stmt_execute mysql_stmt_store_result con el cursor ...

+0

mi ruta del código es como la anterior, mysql_stmt_execute() seguido de mysql_stmt_fetch(). Este es un código "stmt" perfectamente implementado cuando se conecta a un servidor remoto mysql. Sin embargo, genera un error de 'falta de sincronización' cuando se aplica a un servidor incrustado. entonces ... tu respuesta no es relevante. –

Cuestiones relacionadas