Php Yii应用程序未激活触发器

Php Yii应用程序未激活触发器,php,mysql,pdo,yii,Php,Mysql,Pdo,Yii,大家好,StackOverflow的每个人,我是这个网站的粉丝,帮助我走出了无数深渊。但这次我似乎在这里或其他任何地方都找不到答案,我的问题是: 我正在开发一个Yii框架应用程序,用于处理数据库中的数据,保持一致性和一切。基本上,我正在创建一个用于管理数据库信息的接口。我正在使用MySQL 5.0(计划更新到5.5)和InnoDB 我的开发是为了支持一个已经存在的模式(我称之为main),它有几个设计问题。我们的目标是用一个新的、设计正确的模式(我称之为shadow)替换旧模式。但与此同时,我们

大家好,StackOverflow的每个人,我是这个网站的粉丝,帮助我走出了无数深渊。但这次我似乎在这里或其他任何地方都找不到答案,我的问题是:

我正在开发一个Yii框架应用程序,用于处理数据库中的数据,保持一致性和一切。基本上,我正在创建一个用于管理数据库信息的接口。我正在使用MySQL 5.0(计划更新到5.5)和InnoDB

我的开发是为了支持一个已经存在的模式(我称之为main),它有几个设计问题。我们的目标是用一个新的、设计正确的模式(我称之为shadow)替换旧模式。但与此同时,我们正在尝试将新模式实现为主模式的影子模式,并通过触发器保持更改的一致性

所有重要的更改都是对影子模式进行的,它使用触发器将影子模式反映到主模式。这两个模式都托管在同一台服务器上,无论何时通过命令行客户端或使用MySQL Workbench进行更改,触发器都能很好地反映从shadow到main的数据更改,但无论何时使用Yii应用程序对shadow数据进行更改。。。这些更改只对影子模式进行,而不会反映到主模式

这是shadow.tbl_设备的描述和触发DDL:

mysql> use shadow;
mysql> describe tbl_device;
+--------------+-------------+------+-----+-------------------+-----------------------------+
| Field        | Type        | Null | Key | Default           | Extra                       |
+--------------+-------------+------+-----+-------------------+-----------------------------+
| Id           | int(11)     | NO   | PRI | NULL              | auto_increment              |
| SerialNumber | varchar(40) | NO   |     | NULL              |                             |
| State        | varchar(20) | NO   | MUL | Recién Llegado    |                             |
| ProviderId   | int(11)     | NO   | MUL | NULL              |                             |
| OwnerId      | int(11)     | NO   | MUL | NULL              |                             |
| ProfileId    | int(11)     | YES  | MUL | NULL              |                             |
| ChipId       | int(11)     | YES  | UNI | NULL              |                             |
| IMEI         | varchar(15) | YES  |     | NULL              |                             |
| ModelNumber  | varchar(20) | YES  |     | NULL              |                             |
| FirstUsed    | date        | YES  |     | NULL              |                             |
| Brand        | varchar(45) | NO   | MUL | No Definida       |                             |
| Agreement    | varchar(20) | NO   | MUL | No Establecido    |                             |
| LastUpdated  | timestamp   | NO   |     | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+--------------+-------------+------+-----+-------------------+-----------------------------+
13 rows in set (0.01 sec)

-- Trigger DDL Statements

USE `shadow`$$

CREATE
DEFINER=`root`@`localhost`
TRIGGER `shadow`.`trg_device_after_insert_produce_location_and_register_device`
AFTER INSERT ON `shadow`.`tbl_device`
FOR EACH ROW
BEGIN
    DECLARE NumCel VARCHAR(10) DEFAULT NULL;
    INSERT INTO tbl_location(DeviceId) values (New.Id);
    IF New.ChipId IS NOT NULL THEN
        SELECT CONCAT(AreaCode,Phone) INTO NumCel FROM tbl_chip WHERE Id = New.ChipId;
    END IF;

    IF New.Brand = 'Navcel' THEN
        INSERT INTO navcel.detalle_aplicacion(apId, pdRadioId, adActivo) values (1,CAST(New.SerialNumber as UNSIGNED), 1);
    END IF;
    IF New.Brand = 'Calamp' Then
        INSERT INTO main.equipos(eqId,eqNumCel,shadowDeviceId) values (CONV(SUBSTRING(New.SerialNumber,-6),16,10),NumCel,New.Id);
    ELSE
        INSERT INTO main.equipos(eqId,eqNumCel,shadowDeviceId) values (CAST(New.SerialNumber as UNSIGNED),NumCel,New.Id);
    END IF;
END$$

CREATE
DEFINER=`root`@`localhost`
TRIGGER `shadow`.`trg_device_after_update_reflect_changes`
AFTER UPDATE ON `shadow`.`tbl_device`
FOR EACH ROW
BEGIN
    DECLARE acuerdo TINYINT(4);
    DECLARE NumCel VARCHAR(10);
    DECLARE eqIdToUpdate INT;
    IF New.LastUpdated <> Old.LastUpdated THEN
        /* UPDATING THE REFLECTION OF THIS DEVICE IN THE main SCHEMA */
        IF New.Agreement = 'Renta' THEN set acuerdo := 1;
            ELSEIF New.Agreement = 'Venta' THEN set acuerdo := 2;
            ELSEIF New.Agreement = 'Prestamo' THEN set acuerdo := 3;
            ELSE set acuerdo := 0;
        END IF;
        IF New.ChipId IS NULL THEN 
            SET NumCel = NULL;
        ELSE 
            Select CONCAT(AreaCode,Phone) INTO NumCel FROM tbl_chip WHERE Id = New.ChipId;
        END IF;
        UPDATE main.equipos SET 
            eqId := New.SerialNumber,
            eqInstalado := 1,
            eqAcuerdo := acuerdo,
            eqNumCel := NumCel
        WHERE shadowDeviceId = New.id;
    END IF;
END$$
我认为该表(由触发器引用)也可能具有相关性:

mysql> describe shadow.tbl_chip;
+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| Id           | int(11)     | NO   | PRI | NULL    | auto_increment |
| ProviderId   | int(11)     | NO   | MUL | NULL    |                |
| OwnerId      | int(11)     | YES  | MUL | NULL    |                |
| ChipState    | varchar(15) | NO   | MUL | Nuevo   |                |
| AreaCode     | varchar(3)  | NO   |     | NULL    |                |
| Phone        | varchar(7)  | NO   |     | NULL    |                |
| SerialNumber | varchar(45) | NO   |     | NULL    |                |
| PIN          | varchar(4)  | YES  |     | NULL    |                |
| PUK          | varchar(45) | YES  |     | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+
9 rows in set (0.02 sec)
所以,基本上。。。无论何时通过命令行/mysql工作台发送查询,都会触发触发器,但无论何时通过yii(与两个DB模式托管在同一台服务器上)发送查询,都不会触发触发器。我看到了以下几点:

依照

MySQL触发器仅由SQL语句激活。它们不会被不将SQL语句传输到MySQL服务器的API在表中所做的更改激活;特别是,它们不会被使用NDB API进行的更新激活

非常感谢您的帮助或指导。提前谢谢


编辑:Yii使用PDO执行insert/update语句,并且insert成功反映,更新仍然失败。

首先:尝试使用Yii应用程序使用的同一mysql用户从控制台/工作台对其进行调试

Yii仍然使用常规SQL语句,而不是您引用的文档中提到的api调用

继续并放入config/main.php文件

组件/数据库部分:

'enableParamLogging' => true
    'log' => array(
        'class' => 'CLogRouter',
        'routes' => array(
            array(
                'class'=>'CFileLogRoute',
                'levels'=>'trace,log',
                'categories' => 'system.db.CDbCommand',
                'logFile' => 'db.log',
            ),
        ),
    ),
和组件/日志部分:

'enableParamLogging' => true
    'log' => array(
        'class' => 'CLogRouter',
        'routes' => array(
            array(
                'class'=>'CFileLogRoute',
                'levels'=>'trace,log',
                'categories' => 'system.db.CDbCommand',
                'logFile' => 'db.log',
            ),
        ),
    ),
然后观察在protected/runtime/db.log中执行的sql命令:

$ tail -f db.log

另外,您确定在更新主触发器更新卷影触发器更新主触发器更新卷影触发器时,不会陷入无休止的循环中吗

我在更新后使用的触发器
有一个子句,以某种方式阻止在触发器内进行更改(实际上总是触发)

创建
DEFINER=`root`@`localhost`
触发'shadow`.'trg\u device\u更新后\u反映\u更改`
更新“shadow”之后。`tbl\U设备`
每行
开始
申报acuerdo TINYINT(4);
宣布NumCel VARCHAR(10);
声明eqIdToUpdate INT;
如果New.LastUpdated Old.LastUpdated,则
...
如果结束;
结束$$

似乎
New.LastUpdated Old.LastUpdated
在从Yii更新时为false,但在从CLI或WorkBench更新时为true。因为在Yii应用程序上,我没有收到tbl_device.LastUpdated的输入(我本来希望MySQL为我做这项工作,现在我觉得有点笨,我可以使用
beforeSave()
方法来更新时间戳字段,我正在使用它来验证是否确实对记录进行了更改…)

使用同一用户进行调试:它在工作台上工作,在命令行cliend上工作,在yii上不工作。我不熟悉那个unix(是unix吗?)命令,但我正在手动检查db.log,发现很多select查询(对应于fk引用验证等,一切都很顺利)…日志中唯一的更新行是:
2012/10/29 23:46:38[trace][system.db.CDbCommand]执行SQL:update“tbl_device”SET“Id=:yp0,“SerialNumber”=:yp1,“State”=:yp2,“ProviderId”=:yp3,“OwnerId”=:yp4,“ProfileId”=:yp5,“ChipId”=:yp6,“IMEI”=:yp7,“ModelNumber”=:yp8,“FirstUsed”=:yp9,“Brand”=:yp10,“Agreement”=:yp11,“LastUpdated”=:yp12其中“tbl_设备”。“Id”=670。绑定:yp0=670,:yp1='ADSF564ASD9F132CX1',:yp2='Recién Llegado',:yp3=12,:yp4=5,:yp5=NULL,:yp6=11,:yp7='123',:yp8='AD3F48C135',:yp9=NULL,:yp10='Skywave',:yp11='No Establecido',:yp12='2012-10-29 15:33'
,没有其他重要行,只选择用于验证和相关记录格式化显示。更改没有反映到主架构中,所以我猜是
shadow。在
shadow上更新后尝试设备\u反映更改
。tbl\u设备
显然没有激活..我已经解决了问题,似乎是验证错误,请查看我自己的答案。。谢谢你含蓄地教我如何配置我的日志。查看如何填写时间戳字段。