MySQL设计;带有变量的视图或存储过程

Posted

技术标签:

【中文标题】MySQL设计;带有变量的视图或存储过程【英文标题】:MySQL design; View or Stored Procedure with variable 【发布时间】:2012-11-05 07:53:56 【问题描述】:

我要执行一个复杂的查询,从 7-8 个表中选择几列。

我们不想用编程语言(php - Symfony 1.4/Propel 1.4 在我们的例子中)编写该查询,而是创建一个视图或存储过程,以便为开发人员提供非常简单的选择查询。我很困惑什么是更好的方法。

我们需要以下格式的查询:

SET @PlayerId = 1;

SELECT CASE WHEN mat.player1id = @PlayerId THEN mat.player2id ELSE mat.player1id END as opponent
    /*plus many other columns*/
FROM `wzo_matches` as mat /*plus few other tables*/
WHERE (mat.player1id =@PlayerId OR mat.player2id=@PlayerId)
    /*plus other join conditions*/

视图的问题是,SET @PlayerId=xx 语句。我们事先不知道玩家 ID,但会通过 PHP 传递。我希望这是排除观点的原因;有什么解决方法吗?

其他选项将是存储过程。唯一的问题是,它将为每个查询创建一个新视图,因此对 DB 的操作将非常繁重。

有人可以建议最好的方法,以便开发人员可以从上面的查询中获取所需的数据,而无需在 PHP 中编写上面的复杂查询。 (显然是通过 SP 或从那里查看和简单的选择查询)

【问题讨论】:

【参考方案1】:

根据Can I create view with parameter in mysql? 的回复,我的问题已通过以下查询解决:

create function getPlayer() returns INTEGER DETERMINISTIC NO SQL return @getPlayer;

create view getPlay as
    SELECT
        CASE WHEN play.hiderid = getPlayer() THEN play.seekerid ELSE play.hiderid END AS opponent, play . * 
        FROM odd_play play, odd_match mat
        WHERE (seekerid = getPlayer() OR hiderid = getPlayer())
        AND play.id = mat.latestplay;

select play.*
from (select @getPlayer:=1 p) ply, getPlay play;

【讨论】:

【参考方案2】:
CREATE PROCEDURE SELECT_PLAYER(p INT) SET @PlayerId  = p
SELECT CASE WHEN mat.player1id = @PlayerId THEN mat.player2id ELSE mat.player1id END as opponent
    /*plus many other columns*/
FROM `wzo_matches` as mat /*plus few other tables*/
WHERE (mat.player1id =@PlayerId OR mat.player2id=@PlayerId)
    /*plus other join conditions*/

【讨论】:

问题的重点是,我不想在 PHP 上使用该查询。在生产环境中,我们不想为所有表授予对 PHP 应用程序的读取权限,因为数据不属于该应用程序。 PHP 应用程序应该只获取它所需要的。

以上是关于MySQL设计;带有变量的视图或存储过程的主要内容,如果未能解决你的问题,请参考以下文章

MySQL视图存储过程触发器

mysql视图,存储过程,函数,事务,触发器,以及动态执行sql

mysql-视图触发器事务存储过程流程控制

数据库存储过程,Mysql视图,Mysql语句

无法使用存储过程过滤带有 % mysql 的行

在存储过程中使用表变量而不是仅从表或视图中选择?