12

我做了一个存储过程。我希望它通过不同的参数过滤数据。如果我传递一个参数,它应该被一个过滤;如果我通过两个,它应该被两个过滤,依此类推,但它不起作用。

任何人都可以帮助我吗?

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;
4

2 回答 2

12

AFAIK,你不能有这样的变量参数列表。您可以做以下几件事之一:

  1. 采用固定的最大参数数量,并在连接之前检查它们是否为空:

    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''')
    
  2. 获取一个远大于 45 个字符的参数,然后简单地将其附加到查询中(假设它不为空)。

    显然,这使用户有责任提供正确的 SQL 代码。

    可能的调用:

    CALL SP_rptProvince2('RegionName = ''North'' AND column3 = ''South''')
    

两者之间没有太多选择。任何一个都可以工作;两者都不完全令人满意。

您可能会注意到需要用额外的引号保护参数中的字符串;这就是造成问题的原因。

于 2012-04-29T04:22:22.837 回答
3

我发现了一种基于 JSON 的方法,它适用于最新的 MySQL/MariaDB 系统。检查下面的链接(原作者是 Federico Razzoli):https://federico-razzoli.com/variable-number-of-parameters-and-optional-parameters-in-mysql-mariadb-procedures

基本上,您采用一个实际上是 JSON 对象的 BLOB 参数,然后根据需要执行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;
于 2019-07-26T10:49:59.990 回答