我正在尝试为MySQL创建用户定义的函数(根据本文档https://dev.mysql.com/doc/extending-mysql/8.0/en/adding-loadable-function.html)并创建新命令my_udf 将通过系统调用运行 Python 脚本,但它不起作用。
#include <mysql/mysql.h>
#include <string>
#include <iostream>
#include <cstring>
extern "C" bool my_udf_init(UDF_INIT* initid, UDF_ARGS* args, char* message)
{
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
strcpy(message, "Expected a single string argument");
return 1;
}
initid->const_item = 1; // This UDF is deterministic
initid->maybe_null = 1; // This UDF can return NULL
initid->max_length = 0; // The result can be of any length
return 0;
}
extern "C" char* my_udf(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* length, char* is_null, char* error)
{
// Print the input string
// Run the Python script and pass the input string as a command-line parameter
char param[] = "params to script";
char cmd[100];
sprintf(cmd, "python3 checker.py %s", param);
system(cmd);
return 0;
}
我的Python脚本一切正常,我检查了两次。
我认为调用系统(cmd)有问题。
由于 MySQL 的安全限制和权限问题,使用 system() 从 MySQL UDF 运行 Python 脚本可能会出现问题。相反,使用 popen() 执行脚本并捕获其输出。这是代码的重构版本:
#include <mysql/mysql.h>
#include <string>
#include <cstdio>
extern "C" bool my_udf_init(UDF_INIT* initid, UDF_ARGS* args, char* message) {
if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) {
strcpy(message, "Expected a single string argument");
return 1;
}
initid->const_item = 1;
initid->maybe_null = 1;
initid->max_length = 0;
return 0;
}
extern "C" char* my_udf(UDF_INIT* initid, UDF_ARGS* args, char* result,
unsigned long* length, char* is_null, char* error) {
char cmd[200];
sprintf(cmd, "python3 checker.py %s", args->args[0]);
FILE* pipe = popen(cmd, "r");
if (!pipe) {
strcpy(error, "Failed to run command");
return NULL;
}
char buffer[128];
std::string output = "";
while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
output += buffer;
}
pclose(pipe);
*length = output.size();
strcpy(result, output.c_str());
return result;
}
使用 popen() 运行 Python 脚本。 确保MySQL用户具有执行命令的正确权限。 如果您还有其他问题,请检查 MySQL 日志中是否有与权限相关的错误。