我已经制作了一个存储过程。我希望它通过不同的参数过滤数据。如果我传递一个参数,它应该被一个过滤;如果我通过两个,它应该被两个过滤,依此类推,但它不起作用。
有人可以帮我吗?
DROP PROCEDURE IF EXISTS medatabase.SP_rptProvince2;
CREATE PROCEDURE medatabase.`SP_rptProvince2`(
IN e_Region VARCHAR(45)
)
BEGIN
DECLARE strQuery VARCHAR(1024);
DECLARE stmtp VARCHAR(1024);
SET @strQuery = CONCAT('SELECT * FROM alldata where 1=1');
IF e_region IS NOT NULL THEN
SET @strQuery = CONCAT(@strQuery, ' AND (regionName)'=e_Region);
END IF;
PREPARE stmtp FROM @strQuery;
EXECUTE stmtp;
END;
答案 0 :(得分:11)
AFAIK,你不能拥有这样的变量参数列表。你可以做以下几件事之一:
获取固定的最大参数数量,并在连接之前检查它们是否为null:
CREATE PROCEDURE SP_rptProvince2(a1 VARCHAR(45), a2 VARCHAR(45), ...)
...
IF a1 IS NOT NULL THEN
SET @strQuery = CONCAT(@strQuery, ' AND ', a2);
END IF;
如果您需要应用参数中的条件的预定字段(如现有代码中的e_Region
参数),则可以适当地修改CONCAT操作。
可能的调用:
CALL SP_rptProvince2('''North''', 'column3 = ''South''')
获取一个比45个字符大得多的参数,只需将其附加到查询中(假设它不为空)。
显然,这会给用户带来责任,提供正确的SQL代码。
可能的调用:
CALL SP_rptProvince2('RegionName = ''North'' AND column3 = ''South''')
两者之间没有太多选择。要么可以工作;既不完全令人满意。
您可能会注意到需要使用额外的引号保护参数中的字符串;这就是导致这个问题的原因。
答案 1 :(得分:0)
我发现了一种基于JSON的方法,可以与最新的MySQL / MariaDB系统一起使用。检查下面的链接(原作者是Federico Razzoli):https://federico-razzoli.com/variable-number-of-parameters-and-optional-parameters-in-mysql-mariadb-procedures
基本上,您可以获取一个BLOB参数,该参数实际上是一个JSON对象,然后根据需要执行 JSON_UNQUOTE(JSON_EXTRACT(json_object,key)) 。
在此处提取摘录:
CREATE FUNCTION table_exists(params BLOB)
RETURNS BOOL
NOT DETERMINISTIC
READS SQL DATA
COMMENT '
Return whether a table exists.
Parameters must be passed in a JSON document:
* schema (optional). : Schema that could contain the table.
By default, the schema containing this procedure.
* table : Name of the table to check.
'
BEGIN
DECLARE v_table VARCHAR(64)
DEFAULT JSON_UNQUOTE(JSON_EXTRACT(params, '$.table'));
DECLARE v_schema VARCHAR(64)
DEFAULT JSON_UNQUOTE(JSON_EXTRACT(params, '$.schema'));
IF v_schema IS NULL THEN
RETURN EXISTS (
SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE
TABLE_SCHEMA = SCHEMA()
AND TABLE_NAME = v_table
);
ELSE
RETURN EXISTS (
SELECT TABLE_NAME
FROM information_schema.TABLES
WHERE
TABLE_SCHEMA = v_schema
AND TABLE_NAME = v_table
);
END IF;
END;