Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL:使用替换为联接?_Mysql_Join_Replace - Fatal编程技术网

MySQL:使用替换为联接?

MySQL:使用替换为联接?,mysql,join,replace,Mysql,Join,Replace,我需要替换文本字段中的多个不同单词 搜索和替换值位于另一个表中 例如,文本表是: The Quick Brown Fox The Dirty Red Bandana 使用如下所示的替换表: SearchValue ReplaceValue Quick Slow Fox Wolf Dirty Clean Bandana Hat 然后,被替换的记录将成为

我需要替换文本字段中的多个不同单词

搜索和替换值位于另一个表中

例如,文本表是:

The Quick Brown Fox
The Dirty Red Bandana
使用如下所示的替换表:

SearchValue         ReplaceValue
  Quick               Slow
  Fox                 Wolf
  Dirty               Clean
  Bandana             Hat
然后,被替换的记录将成为:

The Slow Brown Wolf
The Clean Red Hat
是否可以使用联接来执行此操作

比如:

UPDATE texts_table AS tt
CROSS JOIN values_table AS vt
SET tt.Text= REPLACE(tt.Text, vt.SearchValue, vt.ReplaceValue)

我尝试了一些不同的方法,但无法让它替换文本字段中的所有字符串

您需要指定连接条件,例如:

UPDATE texts_table AS tt
INNER JOIN values_table AS vt 
   on tt.valueId = vt.valudId /*or whatever the join condition*/ 
SET tt.Text= REPLACE(tt.Text, vt.SearchValue, vt.ReplaceValue)
如本条款语法所述:

table_references子句列出了联接中涉及的表。描述了它的语法


JOIN
是错误的方法。
联接的结果行是通过组合每个联接表中的单行来创建的。这与你想做的事情不匹配。对于
SELECT
,将
JOIN
groupby
组合使用会更有意义,尽管
UPDATE
中没有
groupby
子句,因此这不是一个选项

SQL不是为这种文本操作而设计的。它应该由编程语言执行,而不是数据语言

对于
选择
,您可以通过编写一个函数来强制SQL完成这项工作,例如:

/**
 * make_string: Strings hold both character sequence and a length. Strings can 
 * hold null characters and are null terminated for safety, in case they hold 
 * C-strings, but the null character shouldn't be used as a terminator by any 
 * string function.
 *
 * @param data: characters to copy to string
 * @param len: number of characters to copy from data
 * @param size: number of characters to allocate; lets you allocate extra space. 
 *     If size < len, size is set to len, so you can pass 0 to not allocate 
 *     extra space.
 */
string_t* make_string(const char *data, int len, int size);
string_t* delete_string(string_t* str);
char* string_data(string_t* str);
int string_length(string_t* str);
/**
 * Copy data to str's buffer, replacing whatever was stored there previously.
 *
 * @returns 0 on success, non-0 on failure.
 */
int string_set(string_t* str, const char* data, int len);
/**
 * Replace first occurrence of 'search' in 'str' with 'replace', starting the 
 * search at character 'start'.
 *
 * If there isn't enough space in str's buffer, resize the buffer. If there is 
 * enough space, must always succeed.
 *
 * @returns position of character after replaced section, or -1 if search isn't found.
 */
int string_replace(string_t* str, string_t* search, string_t* replace, int start);
...

my_bool group_replace_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 3) {
        strcpy(message,"wrong argument count: group_replace(str, search, replacement) requires three string arguments");
        return 1;
    }
    initid->maybe_null = 1;
    initid->max_length = args->lengths[0];
    if (! (initid->ptr = make_string("", 0, args->lengths[0])) ) {
        snprintf(message, MYSQL_ERRMSG_SIZE, "error allocating string for group_replace: %s", strerror(errno));
        return 1;
    }
    return 0;
}

void group_replace_deinit(UDF_INIT *initid) {
    delete_string(initid->ptr);
}

void group_replace_clear(UDF_INIT *initid, char *is_null, char *error) {
    string_set(initid->ptr, "", 0);
    // result will be null, until 
    *is_null = 1;
    *error = 0;
}

void group_replace_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
    if (*error) {
        return;
    }
    if (*is_null && args->args[0]) {
        if (string_set(initid->ptr, args->args[0], args->lengths[0])) {
            *error = 1;
            return;
        }
        *is_null = 0;
    }
    string_t *search, *replacement;
    if (! (search = make_string(args->args[1], args->lengths[1])) ) {
        *error = 1;
        return;
    }
    if (! (replacement = make_string(args->args[2], args->lengths[2])) ) {
        delete_string(search);
        *error = 1;
        return;
    }
    int pos=0;
    do {
        pos = string_replace(initid->ptr, search, replacement, pos);
    } while (0 <= pos);
}
char* group_replace(UDF_INIT *initid, UDF_ARGS *args,
                    char *result, unsigned long *length,
                    char *is_null, char *error)
{
    if (*is_null) {
        *length = 0;
        return null;
    }
    *length = string_length(initd->ptr);
    return string_data(initid->ptr);
}

我省略了ON条件,因为我不知道如何指定它,而且仍然不知道。如果我使用交叉联接(无条件),在texts_表中有2条记录,则在某种程度上只替换最后一条记录中的最后一个字。@Dylan您需要根据表的结构和要选择的数据指定联接子句,以便更新它,
交叉联接
会将第一个表中的每一行与第二个表中的每一行合并,这样就得到了两个表中的行的笛卡尔乘积,所以我认为这对您不起作用。所以尝试使用左连接或其他连接。
/**
 * make_string: Strings hold both character sequence and a length. Strings can 
 * hold null characters and are null terminated for safety, in case they hold 
 * C-strings, but the null character shouldn't be used as a terminator by any 
 * string function.
 *
 * @param data: characters to copy to string
 * @param len: number of characters to copy from data
 * @param size: number of characters to allocate; lets you allocate extra space. 
 *     If size < len, size is set to len, so you can pass 0 to not allocate 
 *     extra space.
 */
string_t* make_string(const char *data, int len, int size);
string_t* delete_string(string_t* str);
char* string_data(string_t* str);
int string_length(string_t* str);
/**
 * Copy data to str's buffer, replacing whatever was stored there previously.
 *
 * @returns 0 on success, non-0 on failure.
 */
int string_set(string_t* str, const char* data, int len);
/**
 * Replace first occurrence of 'search' in 'str' with 'replace', starting the 
 * search at character 'start'.
 *
 * If there isn't enough space in str's buffer, resize the buffer. If there is 
 * enough space, must always succeed.
 *
 * @returns position of character after replaced section, or -1 if search isn't found.
 */
int string_replace(string_t* str, string_t* search, string_t* replace, int start);
...

my_bool group_replace_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
    if (args->arg_count != 3) {
        strcpy(message,"wrong argument count: group_replace(str, search, replacement) requires three string arguments");
        return 1;
    }
    initid->maybe_null = 1;
    initid->max_length = args->lengths[0];
    if (! (initid->ptr = make_string("", 0, args->lengths[0])) ) {
        snprintf(message, MYSQL_ERRMSG_SIZE, "error allocating string for group_replace: %s", strerror(errno));
        return 1;
    }
    return 0;
}

void group_replace_deinit(UDF_INIT *initid) {
    delete_string(initid->ptr);
}

void group_replace_clear(UDF_INIT *initid, char *is_null, char *error) {
    string_set(initid->ptr, "", 0);
    // result will be null, until 
    *is_null = 1;
    *error = 0;
}

void group_replace_add(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error) {
    if (*error) {
        return;
    }
    if (*is_null && args->args[0]) {
        if (string_set(initid->ptr, args->args[0], args->lengths[0])) {
            *error = 1;
            return;
        }
        *is_null = 0;
    }
    string_t *search, *replacement;
    if (! (search = make_string(args->args[1], args->lengths[1])) ) {
        *error = 1;
        return;
    }
    if (! (replacement = make_string(args->args[2], args->lengths[2])) ) {
        delete_string(search);
        *error = 1;
        return;
    }
    int pos=0;
    do {
        pos = string_replace(initid->ptr, search, replacement, pos);
    } while (0 <= pos);
}
char* group_replace(UDF_INIT *initid, UDF_ARGS *args,
                    char *result, unsigned long *length,
                    char *is_null, char *error)
{
    if (*is_null) {
        *length = 0;
        return null;
    }
    *length = string_length(initd->ptr);
    return string_data(initid->ptr);
}
SELECT tt.id, GROUP_REPLACE(tt.Text, vt.SearchValue, vt.ReplaceValue)
  FROM texts_table AS tt
    JOIN values_table AS vt ON INSTR(tt.Text, vt.SearchValue) > 0
  GROUP BY tt.id
;