【问题标题】:User-defined routine in Doctrine 1.2?Doctrine 1.2 中的用户定义例程?
【发布时间】:2011-09-12 04:29:07
【问题描述】:

我必须为我的 MySQL 数据库编写一个用户定义的例程(计算距离函数)。

  1. 是否可以在 yaml 架构文件中定义?

在终端 mysql-client 中定义例程后一切正常,直到 'doctrine build-all-reload' - 功能被删除,这是可以理解的;

  1. 如何附加每次运行“build-all-reload”时都会执行的 sql 脚本?

对不起我的英语。 汤姆

【问题讨论】:

    标签: php mysql doctrine user-defined routines


    【解决方案1】:

    我通过在我的学说.php 文件中添加以下行找到了一个解决方案(在某些方面类似于您的解决方案):

    $q = file_get_contents('../configs/sql/routines.sql');
    $conn = Doctrine_Manager::connection();
    $conn->execute($q);
    

    现在,每次我执行 ./doctrine build-all-reload 时都会执行以下脚本:

    DROP FUNCTION IF EXISTS DIST;
    CREATE FUNCTION DIST (fi11 DOUBLE, ksi11 DOUBLE, fi22 DOUBLE, ksi22 DOUBLE)
      RETURNS DOUBLE
       DETERMINISTIC
        BEGIN
         DECLARE d DOUBLE;
         DECLARE fi1 DOUBLE;
         DECLARE fi2 DOUBLE;
         DECLARE ksi1 DOUBLE;
         DECLARE ksi2 DOUBLE;
         SET fi1 = PI()*(fi11)/180;
         SET fi2 = PI()*(fi22)/180;
         SET ksi1 = PI()*(ksi11)/180;
         SET ksi2 =PI()*(ksi22)/180;
         SET d = ACOS((SIN(fi1)*SIN(fi2))+(COS(fi1)*COS(fi2)*COS((ksi1-ksi2))))*6371.0;
         RETURN d;
        END;
    

    这个解决方案可能并不优雅,但对我有用:) 我不打算从 MySQL 更改数据库。

    之后我可以在 Doctrine Queries 中使用 DIST 函数,它的工作速度比使用标准内置函数实现快几倍,而且更短。

    $q->where('DIST(a.lan, a.lon, b.lan, b.lon) < ?', array(2.0));
    

    代替

    $q->where('ACOS((SIN(...)... ... wrrrr ;-P ))*6371.0 < ?', array(2.0));
    

    感谢您的帮助。

    【讨论】:

    • 你是不是简单地把execute($q) 加到了doctrine.php 的末尾?问题是如果您将您的教义.php 用于“build-all-reload”以外的任何命令。但是您当然可以为 build-all-reload 制作一个专门的教义.php,在这种情况下,我喜欢您的解决方案 :-)
    • 是的,那一行被添加到了doctrine.php文件的末尾。
    【解决方案2】:

    认为这可以通过教义行为来完成。

    按照我自己的博文 http://darrendev.blogspot.com/2010/03/creating-doctrine-custom-behaviour-part.html,但使用 setUp() 而不是 setTableDefinition(),您可以使用以下代码创建一个文件:

    class DarrenTestable extends Doctrine_Template{
        public function setUp(){
            ...
        }
    }
    

    ... 是您可以影响表格创建的地方。您在 yaml 文件中附加此行为:

    ActsAs:
        DarrenTestable
    

    在“...”部分可能有一种简洁的教义方式来做你需要的事情,但是在浏览了源代码之后我不确定,所以这在在您的应用程序的生命周期内,我会亲自在 Doctrine 之外完成所有工作:

    1. 连接到 MySQL
    2. 发送 SQL 以创建您的函数
    3. 断开连接

    附:另一种方法是在 PHP 中编写距离计算函数作为教义行为(扩展 Doctrine_Record_Listener);作为奖励,您可以获得数据库可移植性。但是它将代码与 Doctrine 联系在一起,因此其他应用程序无法像使用 mysql 例程那样使用该函数。

    【讨论】:

      猜你喜欢
      • 2011-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-23
      相关资源
      最近更新 更多