首页 > 解决方案 > Mysql存储过程:匹配列规则以检索值

问题描述

我有一个存储过程,它ColumnProperty根据与ColumnRule.

例如,

我将执行以下命令以获取ColumnPropertyas 字符串(短)。但问题是当使用 WHERE 过滤ColumnRule时,检索到的值是字符串,最后得到未知类型。

CALL `testing-spGetColumnType`('varchar(11)', @outputProperty);
select @outputProperty;

DELIMITER $$
CREATE PROCEDURE `testing-spGetColumnType`(IN pColumnType varchar(50),OUT pColumnProperty varchar(50))
BEGIN

    SELECT ColumnProperty FROM model_column_type where pColumnType like replace(ColumnRule, 'variable', pColumnType) into pColumnProperty;
    
    SELECT IFNULL(pColumnProperty,'unknown type') into pColumnProperty;

END$$
DELIMITER ;

样品表:

在此处输入图像描述

标签: mysqlstored-procedureswhere-clauseoperator-keyword

解决方案


当 WHERE 子句中的条件针对作为参数stringShort给出的行进行评估时'varchar(11)',它相当于

  WHERE 'varchar(11)' 
   LIKE '%varchar% and SUBSTRING_INDEX(SUBSTRING_INDEX(varchar(11),''('',-1),'')'',1) < 50' 

并且LIKE比较的结果将为 FALSE。

该行的ColumnRule

%varchar% and SUBSTRING_INDEX(SUBSTRING_INDEX(variable,'(',-1),')',1) < 50

是一个。它看起来像 SQL 文本并不重要。在 SELECT 语句的上下文中,它只是一个字符串。这是一个字符串。它不是对标识符、SQL 函数或布尔运算符的引用。

如果ColumnRule值为

%varchar% one two buckle my shoe

要将字符串值视为 SQL 文本,我们可以使用动态准备的 SQL。

在 MySQL PROCEDURE 的上下文中,我们可以动态创建 SQL 文本并将其存储为字符串,然后执行该字符串,如下所示:

 SET @foo = ' foo, bar' ; 
 SET @sql = CONCAT('SELECT ',@foo,' FROM mytab',' ORDER BY ',@foo); 
 PREPARE stmt FROM @sql;
 EXECUTE stmt;
 DEALLOCATE PREPARE stmt;

提醒一句:如果我们动态创建 SQL 文本,并包含潜在的不安全值,我们可以打开一个巨大的 SQL 注入漏洞,ala Little Bobby Tables https://xkcd.com/327/

MySQL 参考https://dev.mysql.com/doc/refman/8.0/en/sql-syntax-prepared-statements.html


推荐阅读