C 프로그램이 MySQL 프로시저에서 결과 값을 가져올 수 없습니다.
MySQL 스토어드 프로시저에서 값을 되돌리는 연습을 하고 있기 때문에 먼저 다음 프로시저를 만들었습니다.
USE testdb;
DROP PROCEDURE IF EXISTS `testdb`.`get_return_value_test`;
DELIMITER $$
CREATE PROCEDURE IF NOT EXISTS `testdb`.`get_return_value_test`(IN a INT(30), IN b INT, OUT result INT)
BEGIN
SET result = a+b;
SELECT result;
END $$
DELIMITER ;
MariaDB 콘솔에서 테스트에 성공했습니다.
MariaDB [testdb]> call get_return_value_test(2, 3, @out_value);
+--------+
| result |
+--------+
| 5 |
+--------+
1 row in set (0.000 sec)
Query OK, 0 rows affected (0.000 sec)
하지만 C프로그램 내에서 사용해야 할 경우 결과가 나오지 않습니다.
mysql_stmt_fetch
함수가 반환되다101
MySQL 문서에서는 본 적이 없는 값mysql_stmt_errno
0 내가 어디가 잘못됐는지 알아?감사해요.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h>
#include "utils.c"
static MYSQL *conn;
static void get_return_value_test(MYSQL *conn)
{
int a = 3;
int b = 4;
int result = -1;
int error_number;
MYSQL_STMT *prepared_stmt;
MYSQL_BIND param[3];
// Prepare stored procedure call
if(!setup_prepared_stmt(&prepared_stmt, "call get_return_value_test(?, ?, @out_value)", conn))
{
printf("Unable to run setup_prepared_stmt\n");
mysql_stmt_close(prepared_stmt);
mysql_close(conn);
exit(EXIT_FAILURE);
}
// Prepare parameters
memset(param, 0, sizeof(param));
param[0].buffer_type = MYSQL_TYPE_LONG;
param[0].buffer = &a;
param[0].buffer_length = sizeof(a);
param[1].buffer_type = MYSQL_TYPE_LONG;
param[1].buffer = &b;
param[1].buffer_length = sizeof(b);
param[2].buffer_type = MYSQL_TYPE_LONG;
param[2].buffer = &result;
param[2].buffer_length = sizeof(result);
if (mysql_stmt_bind_param(prepared_stmt, param) != 0)
{
printf("Could not bind parameters\n");
mysql_stmt_close(prepared_stmt);
mysql_close(conn);
exit(EXIT_FAILURE);
}
// Run procedure
if ((error_number = mysql_stmt_execute(prepared_stmt)) != 0)
{
printf("%d", error_number);
printf("mysql_stmt_execute error.");
mysql_stmt_close(prepared_stmt);
mysql_close(conn);
exit(EXIT_FAILURE);
}
else
{
printf("mysql_stmt_execute correctly executed\n");
}
memset(param, 0, sizeof(param));
if((error_number = mysql_stmt_bind_result(prepared_stmt, param)) != 0)
{
printf("%d", error_number);
printf("Could not retrieve output parameter");
mysql_stmt_close(prepared_stmt);
mysql_close(conn);
exit(EXIT_FAILURE);
}
//FAILS HERE
if((error_number = mysql_stmt_fetch(prepared_stmt)) != 0 )
{
printf("%d\n", error_number);
printf("mysql_stmt_errno is %d\n", mysql_stmt_errno(prepared_stmt));
finish_with_stmt_error(conn, prepared_stmt, "Could not buffer results\n", true);
}
printf("Result is %d\n", result);
mysql_stmt_close(prepared_stmt);
}
int main()
{
conn = mysql_init (NULL);
if (conn == NULL)
{
fprintf (stderr, "mysql_init() failed (probably out of memory)\n");
exit(EXIT_FAILURE);
}
if (mysql_real_connect(conn, "localhost", "login", "login", "testdb", 3306, NULL, CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS) == NULL)
{
fprintf (stderr, "mysql_real_connect() failed\n");
printf(mysql_error(conn));
mysql_close (conn);
exit(EXIT_FAILURE);
}
get_return_value_test(conn);
mysql_close (conn);
return 0;
}
101은 다음과 같은 값으로 정의됩니다.MYSQL_DATA_TRUNCATED
mysql.h에서
https://dev.mysql.com/doc/c-api/8.0/en/mysql-stmt-fetch.html은 다음과 같이 기술하고 있습니다.
MYSQL_DATA_TRUNCATED
는 잘라내기 보고서가 네이블일 때 반환됩니다.이 값이 반환되었을 때 잘린 컬럼 값을 확인하려면 , 의 에러 멤버를 체크해 주세요.MYSQL_BIND
값을 가져오는 데 사용되는 구조입니다.트랜케이션 리포트는 디폴트로 이니블이지만 mysql_options()를 사용하여 제어할 수 있습니다.MYSQL_REPORT_DATA_TRUNCATION
선택.
기본적으로 이 보고 옵션을 활성화하지 않은 이전 버전의 MySQL을 사용 중이었기 때문에 이전에 이 옵션을 보지 못했을 수 있습니다.
2개의 32비트 정수의 합계가 오버플로가 발생할 수 있으므로 함수의 값을 64비트 정수로 반환해야 합니다.
좋아요, 제가 당신의 코드를 자세히 살펴볼게요. 그리고 당신이 그 코드를 재사용하는 걸 봤어요.params
파라미터 바인딩뿐만 아니라 결과 바인딩에 대해서도 어레이를 지정합니다.결과를 얻기 위해 params 어레이를 바인딩하기 전에 memset을 0으로 설정합니다.
그러나 결과 바인딩에 사용되는 어레이는 결과 집합 메타데이터에 따라 일부 값을 초기화해야 합니다.memset을 실행했기 때문에 어레이는 모두 0이 될 것 같습니다.내 생각엔 네가buffer_length
0은 에러가 발생할 수 있는 문제입니다.
따라서 CALL 문에서 결과를 얻는 방법을 보여주는 매뉴얼의 코드 예를 확인하고 결과 버퍼를 초기화하기 위해 동일한 절차를 수행할 것을 권장합니다.
언급URL : https://stackoverflow.com/questions/71550777/c-program-cannot-get-result-value-from-mysql-procedure
'programing' 카테고리의 다른 글
SQL Chemy IN 조항 (0) | 2023.01.01 |
---|---|
Mac OS 10.6(Snow Leopard), 10.7(Lion), 10.8(Mountain Lion)에서 PHP와 MySQL을 활성화하는 가장 쉬운 방법은 무엇입니까? (0) | 2023.01.01 |
int 유형의 리터럴 xyz가 범위를 벗어났습니다. (0) | 2023.01.01 |
PHP에서 datetime을 ISO 8601로 변환하는 방법 (0) | 2022.12.27 |
MariaDb에 연결할 때 MySql Workbench 오류가 발생했습니다.performance_schema.user_variables_by_thread' 테이블이 존재하지 않습니다. (0) | 2022.12.27 |