mysql 错误代码:2013错误代码:2013

8aqjt8rx  于 2024-01-05  发布在  Mysql
关注(0)|答案(1)|浏览(200)

我在MySQL中有以下查询:

  1. SELECT FUNCTIONTEST(Column1, 27, 'SOMETHING', Column2) AS RANK1 FROM table1

字符串

  • Column1* 为varchar(100),Column2 为unsigned tinyint(3),默认值为0。不使用NULL。
  • FUNCTIONTEST* 是一个UDF函数,它以前工作得很好,但我想通过第四个参数来扩展它。

自定义项初始化函数清单:

  1. bool FUNCTIONTEST_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
  2. if ((args->arg_count != 4) ||
  3. (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || args->arg_type[2] != STRING_RESULT || args->arg_type[3] != INT_RESULT)) {
  4. strcpy(message, "Function requires 4 arguments, (string, int, string, int)");
  5. return 1;
  6. }
  7. const longlong abc = *((longlong*) args->args[1]);
  8. const long long def = *((long long*) args->args[3]);


当使用Column2时,最后一行会导致问题。它会生成错误:

  • 错误代码:2013。查询过程中与MySQL服务器失去连接 *

但是,如果我直接用一个数字调用query,而不是使用column,它就可以工作。

  1. SELECT FUNCTIONTEST(Column1, 27, 'SOMETHING', 0) AS RANK1 FROM table1


有谁知道,可能是什么问题?
Column1是一个字符串,可以正常工作(不是代码片段的一部分)。我尝试将Column2改为varchar,但在UDF中将字符串转换为整数时遇到了麻烦。我还尝试在查询中使用 CAST
要复制,请在MySQL中创建以下表格:

  1. SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
  2. START TRANSACTION;
  3. SET time_zone = "+00:00";
  4. /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
  5. /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
  6. /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
  7. /*!40101 SET NAMES utf8mb4 */;
  8. CREATE TABLE `stack` (
  9. `ID` int(11) NOT NULL,
  10. `Name` varchar(100) NOT NULL DEFAULT '',
  11. `Subtract` tinyint(3) UNSIGNED NOT NULL DEFAULT 0
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
  13. INSERT INTO `stack` (`ID`, `Name`, `Subtract`) VALUES
  14. (1, 'Test1 Test2 Test3', 0),
  15. (2, 'Test4 Test5 Test6', 6);
  16. ALTER TABLE `stack`
  17. ADD PRIMARY KEY (`ID`);
  18. ALTER TABLE `stack`
  19. MODIFY `ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3;
  20. COMMIT;
  21. /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
  22. /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
  23. /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;


名为levenshtein.c的UDF文件:

  1. #ifdef STANDARD
  2. /* STANDARD is defined, don't use any mysql functions */
  3. #include <string.h>
  4. #ifdef __WIN__
  5. typedef unsigned __int64 ulonglong; /* Microsofts 64 bit types */
  6. typedef __int64 longlong;
  7. #else
  8. #endif /*__WIN__*/
  9. #else
  10. //#include <my_global.h>
  11. //#include <my_sys.h>
  12. #if defined(MYSQL_SERVER)
  13. #include <m_string.h>
  14. #else
  15. /* when compiled as standalone */
  16. #include <string.h>
  17. #endif
  18. #endif
  19. #include <mysql.h>
  20. #include <ctype.h>
  21. typedef unsigned long long ulonglong;
  22. typedef long long longlong;
  23. //#ifdef HAVE_DLOPEN
  24. /* (Expected) maximum number of digits to return */
  25. #define LEVENSHTEIN_MAX 3
  26. #define INSERT_MULTIPLIER 5000
  27. #define DELETE_MULTIPLIER 0
  28. #define TRANSPOSITION_MULTIPLIER 2000
  29. static inline int minimum(int a, int b, int c) {
  30. int min = a;
  31. if (b < min)
  32. min = b;
  33. if (c < min)
  34. min = c;
  35. return min;
  36. }
  37. #define min4(a,b,c,d) ((a)< (b) ? minimum((a),(c),(d)) : minimum((b),(c),(d)))
  38. static inline int maximum(int a, int b) {
  39. if (a > b) return a;
  40. else return b;
  41. }
  42. #define min(x,y) ((x) < (y) ? (x) : (y))
  43. bool levenshtein2_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
  44. void levenshtein2_deinit(UDF_INIT *initid);
  45. longlong levenshtein2(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);
  46. bool levenshtein2_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
  47. if ((args->arg_count != 4) ||
  48. (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || args->arg_type[2] != STRING_RESULT || args->arg_type[3] != INT_RESULT)) {
  49. strcpy(message, "Function requires 4 arguments, (string, int, string, int)");
  50. return 1;
  51. }
  52. const longlong sl = *((longlong*) args->args[1]);
  53. const long long subtract = *((long long*) args->args[3]);
  54. //const long long subtract = 3;
  55. if (sl <= 0) {
  56. strcpy(message, "Argument 1 must be greater than 0");
  57. return 1;
  58. }
  59. if (subtract < 0) {
  60. strcpy(message, "Argument 3 must be greater or equal to 0");
  61. return 1;
  62. }
  63. if (subtract > sl) {
  64. strcpy(message, "Argument 3 must be lower or greater to argument 1");
  65. return 1;
  66. }
  67. //matrix for levenshtein calculations of size 6 x n+2 x m+2 (+1 for base values and +1 for \0)
  68. int *d = (int *) malloc(sizeof(int) * 6 * (args->lengths[0] + 2) * (args->lengths[2] - subtract + 2));
  69. if (d == NULL) {
  70. strcpy(message, "Failed to allocate memory");
  71. return 1;
  72. }
  73. initid->ptr = (char*) d;
  74. initid->max_length = LEVENSHTEIN_MAX;
  75. initid->maybe_null = 0; //doesn't return null
  76. return 0;
  77. }
  78. void levenshtein2_deinit(UDF_INIT *initid) {
  79. if (initid->ptr != NULL)
  80. free(initid->ptr);
  81. }
  82. longlong levenshtein2(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
  83. // Logic removed from example
  84. longlong bestDistance = 5;
  85. return (longlong) bestDistance;
  86. }


编译为:

  1. gcc -fPIC -o levenshtein.so -shared levenshtein.c `mysql_config --include`


创建函数:

  1. CREATE FUNCTION levenshtein2 RETURNS INT SONAME 'levenshtein.so';


测试查询:

  1. SELECT LEVENSHTEIN2(Name, 17, 'TEST1', Subtract) AS RANK1, stack.* FROM stack


当在levenshtein. c中注解第63行并取消注解第64行时,它可以工作。它也可以与第63行一起工作,它的查询是这样执行的:

  1. SELECT LEVENSHTEIN2(Name, 17, 'TEST1', 3) AS RANK1, stack.* FROM stack

mi7gmzs6

mi7gmzs61#

我目前的解决方法是不验证和使用init函数中第四个参数的值,这意味着我分配了比我需要的更多的内存,但我可以接受,因为它与我以前使用这个函数没有什么不同。

  1. bool levenshtein2_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
  2. if ((args->arg_count != 4) ||
  3. (args->arg_type[0] != STRING_RESULT || args->arg_type[1] != INT_RESULT || args->arg_type[2] != STRING_RESULT || args->arg_type[3] != INT_RESULT)) {
  4. strcpy(message, "Function requires 4 arguments, (string, int, string, int)");
  5. return 1;
  6. }
  7. const longlong sl = *((longlong*) args->args[1]);
  8. //const long long subtract = *((long long*) args->args[3]);
  9. if (sl <= 0) {
  10. strcpy(message, "Argument 1 must be greater than 0");
  11. return 1;
  12. }
  13. //matrix for levenshtein calculations of size 6 x n+2 x m+2 (+1 for base values and +1 for \0)
  14. int *d = (int *) malloc(sizeof(int) * 6 * (args->lengths[0] + 2) * (args->lengths[2] + 2));
  15. if (d == NULL) {
  16. strcpy(message, "Failed to allocate memory");
  17. return 1;
  18. }
  19. initid->ptr = (char*) d;
  20. initid->max_length = LEVENSHTEIN_MAX;
  21. initid->maybe_null = 0; //does not return null
  22. return 0;
  23. }
  24. longlong levenshtein2(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
  25. longlong subtract = *((longlong*) args->args[3]);
  26. if (subtract < 0) {
  27. subtract = 0;
  28. }
  29. int sl = *((int*) args->args[1]);
  30. if (subtract > sl) {
  31. subtract = 0;
  32. }
  33. // Logic removed from example
  34. longlong bestDistance = subtract;
  35. return (longlong) bestDistance;
  36. }

字符串
我仍然不明白,为什么longlong subtract = *((longlong*) args->args[3]);在init函数中不起作用。显然,来自DB的结果是整数,并且根据文档进行了转换。它在main函数中起作用。
如果提供了错误的参数值,我将 subtract 变量更改为0,而不是使函数失败。

展开查看全部

相关问题