テストする簡単な例をハックして、MySql5.1.66で問題を再現できませんでした。ログにPrepare
ステートメントが表示されている場合は、クエリが構文的に正しく、サーバーがパラメーターを受け入れる準備ができていることを示しています。入力パラメータを正しくバインドしないと、Query
ログメッセージは表示されません。
バインドマクロが正しいCコードを生成していることを再度確認する必要があります。次のスニペットは、デバッグに役立ついくつかのアイデアを提供する可能性のあるAPI呼び出しの機能セットを示しています。システムでのバイナリロギングのエラーを回避するためにDETERMINISTIC句を追加するために、関数に加えた唯一の変更。
次のようなテーブルから始めます。
mysql> select * from mytable;
+----+-------+
| id | value |
+----+-------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+-------+
3 rows in set (0.00 sec)
次に、次のクエリを実行すると、次の結果が得られます。
mysql> SELECT lineDistanceC(1.0, 2.0, 3.0, value) FROM mytable;
+-------------------------------------+
| lineDistanceC(1.0, 2.0, 3.0, value) |
+-------------------------------------+
| 248.609129229989 |
| 222.389853289118 |
| 248.609129229989 |
+-------------------------------------+
3 rows in set (0.00 sec)
次のCコードは同じクエリを試行しますが、MySqlAPIを使用します。メモリ管理と正しいエラーチェックは実装されていないことに注意してください。
/* mysql_test.c */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <mysql.h>
int main(int argc, char * argv[])
{
char sqlStr[300];
MYSQL *mysql = mysql_init(NULL);
if (mysql == NULL) {
fprintf(stderr, "ERROR:mysql_init() failed.\n");
exit(1);
}
const char* host = "localhost";
const char* user = "root";
const char* passwd = NULL;
const char* db = "mysql_test";
if (mysql_real_connect(mysql, host, user, passwd, db, 0, NULL, 0) == NULL) {
fprintf(stderr, "ERROR:mysql_real_connect() failed.\n");
exit(1);
}
MYSQL_STMT *statement = NULL;
statement = mysql_stmt_init(mysql);
if (statement == NULL) {
fprintf(stderr, "ERROR:mysql_stmt_init() failed.\n");
exit(1);
}
strcpy (sqlStr, "SELECT lineDistanceC(1.0, 2.0, ?, value) FROM mytable");
if (mysql_stmt_prepare(statement, sqlStr, strlen(sqlStr))) {
fprintf(stderr, "ERROR:mysql_stmt_prepare() failed. Error:%s\nsql:%s\n", mysql_stmt_error(statement), sqlStr);
exit(1);
}
MYSQL_BIND input_bind[1];
memset(input_bind, 0, sizeof(input_bind));
float v1 = 3.0;
unsigned long v1_len = sizeof(v1);
input_bind[0].buffer_type = MYSQL_TYPE_FLOAT;
input_bind[0].buffer = &v1;
input_bind[0].buffer_length = sizeof(v1);
input_bind[0].length = &v1_len;
input_bind[0].is_null = (my_bool*)0;
if (mysql_stmt_bind_param(statement, input_bind)) {
fprintf(stderr, "ERROR:mysql_stmt_bind_param failed\n");
exit(1);
}
if (mysql_stmt_execute(statement)) {
fprintf(stderr, "mysql_stmt_execute(), failed. Error:%s\n", mysql_stmt_error(statement));
exit(1);
}
/* Fetch result set meta information */
MYSQL_RES* prepare_meta_result = mysql_stmt_result_metadata(statement);
if (!prepare_meta_result)
{
fprintf(stderr,
" mysql_stmt_result_metadata(), \
returned no meta information\n");
fprintf(stderr, " %s\n", mysql_stmt_error(statement));
exit(1);
}
/* Get total columns in the query */
int column_count= mysql_num_fields(prepare_meta_result);
if (column_count != 1) /* validate column count */
{
fprintf(stderr, " invalid column count returned by MySQL\n");
exit(1);
}
/* Bind single result column, expected to be a double. */
MYSQL_BIND result_bind[1];
memset(result_bind, 0, sizeof(result_bind));
my_bool result_is_null[1];
double result_double;
unsigned long result_len = 0;
result_bind[0].buffer_type = MYSQL_TYPE_DOUBLE;
result_bind[0].buffer = &result_double;
result_bind[0].buffer_length = sizeof(result_double);
result_bind[0].length = &result_len;
result_bind[0].is_null = &result_is_null[1];
if (mysql_stmt_bind_result(statement, result_bind)) {
fprintf(stderr, "mysql_stmt_bind_Result(), failed. Error:%s\n", mysql_stmt_error(statement));
exit(1);
}
while (!mysql_stmt_fetch(statement)) {
printf("%.12f\n", result_double);
}
}
コンパイル:
gcc -o mysql_test mysql_test.c -lmysqlclient
出力は次のとおりです。
248.609129229989
222.389853289118
248.609129229989
これは、mysqlコマンドラインクライアントを使用して実行されたステートメントの出力と一致します。
これをコンパイルしてシステムで実行し、問題がAPIの使用にあるのか他の問題にあるのかを判断できるはずです。