适当的mysql udf

use*_*537 5 c mysql

我正在尝试为mysql编写一个自定义的用户定义函数,所以我以http://www.mysqludf.org/index.php中的str_ucwords函数为例来构建我自己的函数.

my_bool str_ucwords_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
    /* make sure user has provided exactly one string argument */
    if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT || args->args[0] == NULL)
    {
        strcpy(message,"str_ucwords requires one string argument");
        return 1;
    }

    /* str_ucwords() will not be returning null */
    initid->maybe_null=0;

    return 0;
}

char *str_ucwords(UDF_INIT *initid, UDF_ARGS *args,
    char *result, unsigned long *res_length, 
    char *null_value, char *error)
{
    int i;
    int new_word = 0;

    // copy the argument string into result
    strncpy(result, args->args[0], args->lengths[0]);

    *res_length = args->lengths[0];

    // capitalize the first character of each word in the string
    for (i = 0; i < *res_length; i++)
    {
        if (my_isalpha(&my_charset_latin1, result[i]))
        {
            if (!new_word)
            {
                new_word = 1;
                result[i] = my_toupper(&my_charset_latin1, result[i]);
            }
        }
        else
        {
            new_word = 0;
        }
    }

    return result;
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试,select str_ucwords("test string");但是如果我尝试从数据库中选择一个字段,就像select str_ucwords(name) from name;我没有得到任何回报一样,这种方法很好.

如何更改此功能以便我可以从数据库中的字段中提取数据?

我已经尝试args->arg_type[0] != STRING_RESULT从init函数中删除了.

out*_*tis 2

问题不在于参数的类型,而在于调用它的NULL时间(因为在检索任何行之前调用)。要使用字段,您必须通过在函数中设置为 1来支持 NULL 值,并在实际参数为 null 时设置为 1(并且设置为 NULL,尽管这可能不是必需的) 。str_ucwords_initstr_ucwords_initstr_ucwordsinitid->maybe_null_init*null_valueresultstr_ucwords

my_bool str_ucwords_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    unsigned long res_length;

    /* make sure user has provided exactly one argument */
    if (args->arg_count != 1) {
        snprintf(message, MYSQL_ERRMSG_SIZE, "wrong number of arguments: str_ucwords requires one string argument, got %d arguments", args->arg_count);
        return 1;
    }
    /* make sure user has provided a string argument */
    if (args->arg_type[0] != STRING_RESULT) {
        snprintf(message, MYSQL_ERRMSG_SIZE, "str_ucwords requires one string argument (expected type %d, got type %d)", STRING_RESULT, args->arg_type[0]);
        return 1;
    }

    res_length = args->lengths[0];

    if (SIZE_MAX < res_length) {
        snprintf(message, MYSQL_ERRMSG_SIZE, "res_length (%lu) cannot be greater than SIZE_MAX (%zu)", res_length, (size_t) (SIZE_MAX));
        return 1;
    }

    initid->ptr = NULL;

    if (res_length > 255) {
        char *tmp = (char *) malloc((size_t) res_length); /* This is a safe cast because res_length <= SIZE_MAX. */
        if (tmp == NULL) {
            snprintf(message, MYSQL_ERRMSG_SIZE, "malloc() failed to allocate %zu bytes of memory", (size_t) res_length);
            return 1;
        }
        initid->ptr = tmp;
    }

    initid->maybe_null = 1;
    initid->max_length = res_length;
    return 0;
}

char *str_ucwords(UDF_INIT *initid, UDF_ARGS *args,
            char *result, unsigned long *res_length,
            char *null_value, char *error)
{
    int i;
    int new_word = 1;

    if (args->args[0] == NULL) {
        result = NULL;
        *res_length = 0;
        *null_value = 1;
    } else {
        if (initid->ptr != NULL) {
            result = initid->ptr;
        }

        // copy the argument string into result
        memcpy(result, args->args[0], args->lengths[0]);
        *res_length = args->lengths[0];

        // capitalize the first character of each word in the string
        for (i = 0; i < *res_length; i++) {
            if (my_isalpha(&my_charset_latin1, result[i])) {
                if (new_word) {
                    new_word = 0;
                    result[i] = my_toupper(&my_charset_latin1, result[i]);
                } else {
                    result[i] = my_tolower(&my_charset_latin1, result[i]);
                }
            } else {
                new_word = 1;
            }
        }
    }
    return result;
}
Run Code Online (Sandbox Code Playgroud)

lib_mysqludf_str 的更高版本应该支持函数中的 NULL 值而无需更改,这意味着它们也应该适用于表列。