gpt4 book ai didi

mysql - 如何在 CentOS 上从 C UDF 连接到 MySQL 数据库

转载 作者:太空宇宙 更新时间:2023-11-04 04:24:21 25 4
gpt4 key购买 nike

我正在尝试从用 C 编写的 UDF 中连接到本地主机上的 MySQL 数据库。我创建了一个用户定义的函数,将其作为插件文件夹中的共享对象提供给 MySQL 数据库,并使 UDF 可用:

CREATE FUNCTION test_udf RETURNS INTEGER SONAME 'test_udf.so';

这意味着我可以使用:

SELECT test_udf();

在调用 test_udf() 时,它应该连接到本地主机上的数据库,从数据库中SELECT 数据,处理数据并在成功时返回一个整数值。

这在 Mac OSX 下完美运行,但我没有机会在 CentOS 7 下运行。只要 UDF 尝试连接到本地主机上的数据库,我就会收到错误:

Can't connect to MySQL server on 'localhost'

当然,我对 my.cnf 进行了适当的设置,并注意了防火墙设置。

有人有想法吗?有没有人试过这样的事情?

此代码使用 gcc 在 Mac 和 CentOS 上都能完美编译。

gcc $(mysql_config —cflags —include —libs) -shared -fPIC -o test_udf.so test_udf.c
/// DEBUG MODE FOR IDE (comment out if UDF need´s to be compiled using gcc from commandline) ///////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//#define DEBUG //<---------- COMMENT OUT IF COMPILATION AS SHARED OBJECT
//#define LINUX
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


/***********************************************************************************************************************
* MySQL udf function prototypes
*
* for STRING functions:
* ++++++++++++++++++++++
* char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length,char *is_null,
* char *error);
*
* for INTEGER functions:
* ++++++++++++++++++++++
* long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
*
* for REAL functions:
* ++++++++++++++++++++++
* double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
*
* for DECIMAL functions:
* ++++++++++++++++++++++
* DECIMAL functions return string values and should be declared the same way as STRING functions.
* ROW functions are not implemented.
*
* Initialization / Deinitialization
* +++++++++++++++++++++++++++++++++
* The initialization and deinitialization functions are declared like this:
* my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
* void xxx_deinit(UDF_INIT *initid);
*
***********************************************************************************************************************/


/***********************************************************************************************************************
* UDF global defines (needed for debug & UDF BOTH!)
***********************************************************************************************************************/
#define QUERY_1 "SELECT * FROM test_table"


/***********************************************************************************************************************
* UDF global defines (needed for debug & UDF)
***********************************************************************************************************************/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifdef DEBUG
#define DEBUG_ON 1 // Debugging mode is on -> for testing in IDE
#else
/***********************************************************************************************************************
* automatic UDF function name generation
***********************************************************************************************************************/
#define DEBUG_ON 0 // Debugging mode is of when compiled as shared object
#define UDF_RETURN_TYPE my_ulonglong // the return value type <---------- TYPE IN RETURN VALUE TYPE
#define UDF_FCT_NAME test_udf // the UDF function name <---------- TYPE IN UDF FUNCTION NAME
#define INIT_FCT_NAME test_udf_init // the UDF init function name <---------- TYPE IN UDF INIT FUNCTION NAME
#define DEINIT_FCT_NAME test_udf_deinit // the UDF deinit function name <---------- TYPE IN UDF DEINIT FUNCTION NAME

#endif



/***********************************************************************************************************************
* Includes
***********************************************************************************************************************/
#ifdef DEBUG
#include <stdio.h>
#include <stdlib.h>
#ifndef LINUX
#include "include/mysql.h"
#else
#include "mysql/mysql.h"
#endif
#include <string.h>
#include "my_mysql_header.h"
#else
#include "my_mysql_header.h"
#ifdef STANDARD
/* STANDARD is defined, don't use any mysql functions */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef __WIN__
typedef unsigned __int64 ulonglong;/* Microsofts 64 bit types */
typedef __int64 longlong;
#else
typedef unsigned long long ulonglong;
typedef long long longlong;
#endif /*__WIN__*/
#else
#include <my_global.h>
#include <my_sys.h>
#if defined(MYSQL_SERVER)
#include <m_string.h>/* To get strmov() */
#else
/* when compiled as standalone */
#include <string.h>
#define strmov(a,b) stpcpy(a,b)
#define bzero(a,b) memset(a,0,b)
#define memcpy_fixed(a,b,c) memcpy(a,b,c)
#endif
#endif
#include <mysql.h>
#include <ctype.h>
#endif


//#endif


#ifndef DEBUG
/***********************************************************************************************************************
* MySQL UDF function prototypes
***********************************************************************************************************************/
my_bool INIT_FCT_NAME(UDF_INIT *initid, UDF_ARGS *args, char *message);
void DEINIT_FCT_NAME(UDF_INIT *initid __attribute__((unused)));
UDF_RETURN_TYPE UDF_FCT_NAME(UDF_INIT* initid,
UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)),
char* error __attribute__((unused)));
#endif


/***********************************************************************************************************************
* Other function prototypes
***********************************************************************************************************************/


/***********************************************************************************************************************
* Other functions
***********************************************************************************************************************/
int finish_with_error(MYSQL *con)
{
mysql_close(con);
return 1;
}


/***********************************************************************************************************************
* MySQL udf function definitions
***********************************************************************************************************************/
#ifdef DEBUG
int main ()
{
#else
my_bool INIT_FCT_NAME(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
if(!(args->arg_count == 0)) {
strcpy(message, "No Arguments expected!");
return 1;
}
return 0;
}


void DEINIT_FCT_NAME(UDF_INIT *initid __attribute__((unused)))
{

}



UDF_RETURN_TYPE UDF_FCT_NAME(UDF_INIT* initid,
UDF_ARGS* args __attribute__((unused)),
char* is_null __attribute__((unused)),
char* error __attribute__((unused)))
{
#endif

MYSQL *con = mysql_init(NULL);

if (con == NULL)
{
fprintf(stderr, "%s\n", mysql_error(con));
exit(1);
}

if (mysql_real_connect(con, ADDRESS, USER, PASSWORD, DATABASE, 0, NULL, 0) == NULL)
{
finish_with_error(con);
}

if (mysql_query(con, QUERY_1))
{
finish_with_error(con);
}

MYSQL_RES *result = mysql_store_result(con);

if (result == NULL)
{
finish_with_error(con);
}

/*
* UDF CODE GOING HERE!
*/

mysql_free_result(result);
mysql_close(con);

return 0;
}

最佳答案

好吧,我终于想出了如何让它工作。

1) 在连接之前添加了 mysql_options:

mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"client");

2) 从 mysql_query 更改为 mysql_real_query

mysql_real_query(&mysql, "select * from new_schema.new_table", 34);

3) 将 my.cnf 设置为:

    [client]
port=3306
socket=/var/lib/mysql/mysql.sock

4) 在 mysql_real_connect 函数中使用 127.0.0.1 而不是“localhost”,否则不会使用配置的套接字

关于mysql - 如何在 CentOS 上从 C UDF 连接到 MySQL 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43210698/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com