简体   繁体   English

MySQL存储过程变量格式在SELECT语句中不起作用

[英]MySQL Stored Procedure variable format not working in SELECT statement

I am having trouble getting a variable to work right in a MySQL Stored Procedure. 我在使变量在MySQL存储过程中正常工作方面遇到困难。 Here is a sample of the stored procedure: 这是存储过程的示例:

BEGIN

DECLARE x_parent varchar(100);
DECLARE term_ids_current varchar(100);
DECLARE term_ids_list INT(100);
DECLARE x_counter INT(11);
DECLARE y_counter INT(11);
DECLARE z_counter INT(11);

SET @term_ids_current = 189;
SET @term_ids_list = @term_ids_current;
SET @y_counter = 0;
SET @z_counter = 0;

parent_child: LOOP
    # used for debugging #
    SET @z_counter = @z_counter + 1;

    # first i check to see if my criteria is met to continue the loop. #
    IF EXISTS (SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (@term_ids_current)) THEN

        # used for debugging #
        SET @y_counter = @y_counter + 1;

        BEGIN

            DECLARE x_finished INT(11) DEFAULT 0;

            DECLARE parent_child_cursor CURSOR FOR
            SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (@term_ids_current);

            # declare NOT FOUND handler
            DECLARE CONTINUE HANDLER 
            FOR NOT FOUND SET x_finished = 1;

            OPEN parent_child_cursor;

                SET @x_counter = 0;

                single_parent: LOOP

                    FETCH parent_child_cursor INTO x_parent;

                    IF x_finished = 1 THEN
                        LEAVE single_parent;
                    ELSEIF @x_counter = 0 THEN
                        SET @term_ids_current = x_parent;
                    ELSE
                        SET @term_ids_current = CONCAT (x_parent,",",@term_ids_current);
                    END IF;

                    SET @x_counter = @x_counter + 1;

                END LOOP single_parent;

                SET @term_ids_list = CONCAT (@term_ids_current,",",@term_ids_list);

            CLOSE parent_child_cursor;

        END;
    ELSE
        LEAVE parent_child;
    END IF;

END LOOP parent_child;

# used for debugging #
SELECT @z_counter, @y_counter, @term_ids_current, @term_ids_list;

END;

In the single_parent loop I am populating the @term_ids_current variable with the results from my query. 在single_parent循环中,我用查询的结果填充@term_ids_current变量。 That variable is then used in the query for the main loop to determine if the criteria is still met. 然后,在主循环的查询中使用该变量来确定是否仍然满足条件。 If it is then my loop happens again. 如果是这样,则我的循环再次发生。 I have tested each step of the procedure as an individual query and the results are accurate. 我已经将该过程的每个步骤作为一个单独的查询进行了测试,结果是准确的。 The problem exists in getting the main query in the parent_child loop to run properly the second time. 该问题在于使parent_child循环中的主查询第二次正常运行。

When I run the SP above against my existing data set, the @term_ids_current variable contains this data set: 当我对现有数据集运行上面的SP时,@ term_ids_current变量包含以下数据集:

218,200,199,198,197,196,195,194,193,192,191,190

What I expect to happen is this data set is now passed in the query for the parent_child loop so that query would now be: 我希望发生的是,此数据集现在已在针对parent_child循环的查询中传递,因此查询现在是:

(SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (218,200,199,198,197,196,195,194,193,192,191,190))

When I run that query manually against my DB, the "IF EXISTS" statement is true meaning my parent_child loop should run again. 当我对数据库手动运行该查询时,“ IF EXISTS”语句为true,这意味着我的parent_child循环应再次运行。 But the loop is stopping after the IF EXISTS statement and not running again. 但是循环在IF EXISTS语句之后停止并且不再运行。 I have verified this with the z_counter and y_counter variable. 我已经使用z_counter和y_counter变量验证了这一点。 Every time I run the SP @z_counter = 2 and @y_counter = 1. So I know the IF statement is moving to the ELSE clause and not running. 每次我运行SP @z_counter = 2和@y_counter = 1时,所以我知道IF语句正在移至ELSE子句并且未运行。

To test this further I updated the SP and manually set my @term_ids_current variable at the end of the parent_child loop to see what would happen. 为了进一步测试,我更新了SP,并在parent_child循环的末尾手动设置了@term_ids_current变量以查看会发生什么。 So at the end of my altered SP I have set @term_ids_current this way: 因此,在更改的SP的结尾,我以这种方式设置了@term_ids_current:

SET @term_ids_current = (190,191,192,193,194,195,196,197,198,199,200,218);

    IF @z_counter = 2 THEN
        LEAVE parent_child;
    END IF;

I added the second IF statement to keep the SP from running an endless loop. 我添加了第二条IF语句,以防止SP运行无限循环。

Now when I execute the SP I get this error message: "MySQL said: #1241 - Operand should contain 1 column(s)." 现在,当我执行SP时,我收到以下错误消息:“ MySQL说:#1241-操作数应包含1列。” So I updated the SP again to SET the @term_ids_current variable, but this time I used double quotes instead of parentheses. 因此,我再次更新了SP以设置@term_ids_current变量,但是这次我使用双引号而不是括号。

SET @term_ids_current = "190,191,192,193,194,195,196,197,198,199,200,218";

With the variable manually set the SP returns the expected result. 通过手动设置变量,SP将返回预期结果。 I have tried to use both CAST and CONVERT in my SELECT statement to have the variable treated as a string. 我试图在SELECT语句中同时使用CAST和CONVERT来将变量视为字符串。 Here is an example: 这是一个例子:

SELECT tt.term_id FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt WHERE tt.parent IN (CONVERT(@term_ids_current,CHAR));

This does not work. 这是行不通的。 If I were doing this in Python I would transform the variable for the SELECT statement with: 如果我在Python中执行此操作,则可以使用以下命令转换SELECT语句的变量:

str(@term_ids_current)

But I cannot find a way to do this same thing in MySQL. 但是我找不到在MySQL中执行相同操作的方法。

So my question is, how can I get my variable @term_ids_current to be treated as a string to work properly in my SELECT statement? 所以我的问题是,如何将我的变量@term_ids_current视为在SELECT语句中可以正常工作的字符串?

The query 查询

SELECT tt.term_id 
FROM `bitnami_wordpress`.`wp_2_term_taxonomy` tt 
WHERE tt.parent IN (@term_ids_current)

will not work if the @term_ids_current is a comma separated string. 如果@term_ids_current是逗号分隔的字符串,将不起作用。 The reason for this is that @term_ids_current is treated as string and not as a set. 这是因为@term_ids_current被视为字符串而不是集合。

Couple of suggestions: 几个建议:

  1. Instead of using a user defined variable (@var) use a temporary table for the current id's 代替使用用户定义的变量(@var),对当前ID使用临时表
  2. It is better to use local variables (declare v_var int) instead of user defined variables in procedures as the scope of the user defined variable is the connection whereas the scope of the local variables is the procedure. 最好在过程中使用局部变量(声明v_var int)而不是用户定义变量,因为用户定义变量的范围是连接,而局部变量的范围是过程。 This matters if your procedure calls other procedures that use same variables. 如果您的过程调用使用相同变量的其他过程,则这很重要。

Try the suggestion given by @slaakso or use find_in_set 尝试@slaakso给出的建议或使用find_in_set

so you need to change the in clause into something similar to your codes 所以您需要将in子句更改为类似于您的代码

WHERE find_in_set(tt.parent,@term_ids_current)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM