我一直在尝试使用动态数量的用户定义变量来执行prepare语句,但是找不到解决我问题的示例。
我有一个mysql存储过程,该过程接受超过15个参数。根据输入参数的值,查询条件被添加到过程或从过程中删除。因此,用户定义的变量也应根据添加到proc中的条件进行更改。那么,有没有办法使用动态的用户定义变量来执行proc?
这是我的示例存储过程,
DELIMITER $$
DROP PROCEDURE IF EXISTS `aaa`$$
CREATE PROCEDURE `aaa`(IN param1 VARCHAR(255),IN param2 VARCHAR(255), IN param3 VARCHAR(255)
,IN param4 VARCHAR(255),IN param5 VARCHAR(255),IN param6 VARCHAR(255),
IN param7 VARCHAR(255),IN param8 VARCHAR(255),IN param9 VARCHAR(255),
IN param10 VARCHAR(255)
)
BEGIN
SET @v1 = param1;
SET @v2 = param2;
SET @v3 = param3;
SET @v4 = param4;
SET @v5 = param5;
SET @v6 = param6;
SET @v7 = param7;
SET @v8 = param8;
SET @v9 = param9;
SET @v10 = param10;
BEGIN
SET @QUERY = CONCAT("SELECT * FROM test.customer where name= 'abcd' ");
IF param1 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field1 = ? ");
END IF;
IF param2 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field2 = ? ");
END IF;
IF param3 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field3 = ? ");
END IF;
IF param4 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field4 = ? ");
END IF;
IF param5 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field5 = ? ");
END IF;
IF param6 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field6 = ? ");
END IF;
IF param7 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field8 = ? ");
END IF;
IF param8 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field8 = ? ");
END IF;
IF param9 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field9 = ? ");
END IF;
IF param10 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY," AND field10 = ? ");
END IF;
PREPARE stmt FROM @QUERY;
EXECUTE stmt using @v1,@v2,.......; -- varies based on the condition satisfied. can we make this dynamic??
DEALLOCATE PREPARE stmt;
END;
END$$
DELIMITER ;
这里是解决方法:
SET @QUERY = CONCAT('SELECT * FROM test.customer where name= ''abcd'' ');
IF param1 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY,' AND field1 = ? ');
ELSE
SET @QUERY = CONCAT(@QUERY,' AND ? IS NULL');
END IF;
IF param2 IS NOT NULL THEN
SET @QUERY = CONCAT(@QUERY,' AND field2 = ? ');
ELSE
SET @QUERY = CONCAT(@QUERY,' AND ? IS NULL');
END IF;
...same for the other params...
PREPARE stmt FROM @QUERY;
EXECUTE stmt using @v1, @v2, @v3, @v4, @v5, @v6, @v7, @v8, @v9, @v10;
DEALLOCATE PREPARE stmt;
此解决方案允许EXECUTE接受相同数量的参数。其中一些将针对该列进行测试,否则将使用IS NULL
进行测试,这将是正确的,因为只有在我们已经知道它们为NULL的情况下,我们才使用该谓词。
注意,我也将"
更改为'
。我建议不要将"
用于字符串定界符,因为其含义可能会根据您的SQL_MODE进行更改。