大家好,我是StackOverflow的粉丝,帮助我摆脱了无数的坑。但是这次我似乎没有在这里或其他地方找到答案,我的问题是这样的:我正在开发一个Yii框架应用程序来处理数据库中的数据,保持一致性和一切。基本上,我正在创建一个处理数据库信息的界面。我正在使用MySQL 5.0(定时更新到5.5)和InnoDB。触发器没有被Yii应用程序激活
我的开发即将支持已经存在的模式(我将其称为main),它有几个设计问题。我们的目标是用一个新的,正确设计的新图案替换旧图案(我将其称为shadow)。但与此同时,我们试图将新模式实现为主模式的阴影模式,并通过触发器保持更改一致。
所有重要更改都是对影子模式进行的,影子模式使用触发器将其反映到主模式。两种模式托管在同一台服务器上,并且每当通过命令行客户端或使用MySQL Workbench进行更改时,触发器都能很好地反映从影子到主数据的更改,但每当使用Yii应用程序对数据进行更改时,仅对阴影模式进行更改,而不触发 - 反映到主模式。
这是shadow.tbl_device描述和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$$
在DDL触发器是为了反映对主要触发器,这里是main.equipos描述(这不使用触发器,目前):
+-----------------------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+------------------+------+-----+---------+-------+
| eqId | int(10) unsigned | NO | PRI | 0 | |
| shadowDeviceId | int(11) | YES | UNI | NULL | |
| eqNumCel | varchar(20) | YES | | NULL | |
| stId | int(10) unsigned | NO | | 0 | |
| TIPO_EQUIPOS_tpId | int(10) unsigned | YES | | NULL | |
| eqNombre | varchar(100) | YES | | NULL | |
| eqNUI | varchar(50) | YES | | NULL | |
| eqModelo | varchar(20) | YES | | NULL | |
| eqPlacas | varchar(20) | YES | | NULL | |
| eqLatitud | decimal(9,6) | YES | | NULL | |
| eqLongitud | decimal(9,6) | YES | | NULL | |
| eqAltitud | float | YES | | NULL | |
| eqSatelite | varchar(20) | YES | | NULL | |
| eqFechaActEq | datetime | YES | | NULL | |
| eqFechaActSer | datetime | YES | | NULL | |
| eqNivelGPRS | float | YES | | NULL | |
| eqIcono | varchar(200) | YES | | NULL | |
| eqTiempoRep | datetime | YES | | NULL | |
| eqVersion | varchar(20) | YES | | NULL | |
| eqLatDinGeo | float | YES | | NULL | |
| eqLonDinGeo | float | YES | | NULL | |
| eqTiempoGeo | datetime | YES | | NULL | |
| eqNumEconomico | varchar(20) | YES | | NULL | |
| eqNumPedido | varchar(20) | YES | | NULL | |
| eqVelocidad | int(10) | YES | | NULL | |
| eqNumSerie | varchar(45) | YES | | | |
| EsGeocercaId | int(10) unsigned | YES | | NULL | |
| eqPuntoCercano | int(10) | NO | | 1 | |
| eqDistanciaCercano | float | NO | | 0 | |
| eqIconoActual | varchar(100) | NO | | 0 | |
| eqStatusDBS | varchar(45) | YES | | | |
| eqTieneDBS | int(1) | NO | | 1 | |
| eqFechaDBS | datetime | YES | | NULL | |
| eqEnAlarma | tinyint(1) | NO | | 0 | |
| eqTipoMascara | int(11) | NO | | 1 | |
| eqAdvComunicacion | int(11) | NO | | 120 | |
| eqFallaComunicacion | int(11) | NO | | 300 | |
| eqStComs | int(11) | YES | | 0 | |
| eqCiudadCercana | int(11) | YES | | NULL | |
| eqDistCiudadCercana | float(11,0) | YES | | NULL | |
| eqUsaGeocercaDinamica | int(1) | NO | | 0 | |
| eqUcStatus | tinyint(4) | NO | | 0 | |
| eqOdometro | float | NO | | 0 | |
| eqBoletin | int(11) | YES | | 0 | |
| eqPaseSalida | int(11) | YES | | 0 | |
| eqMedioTx | varchar(20) | YES | | 0 | |
| eqDigInputs | int(11) | YES | | 0 | |
| eqFechaActEqLocal | datetime | YES | | NULL | |
| eqLatitudCruda | decimal(9,6) | YES | | NULL | |
| eqLongitudCruda | decimal(9,6) | YES | | NULL | |
| eqVelocidadCruda | int(11) | YES | | NULL | |
| eqIconoWeb | varchar(20) | YES | | car | |
| eqUsaAnalogicas | tinyint(4) | NO | | 0 | |
| eqInstalado | tinyint(4) | YES | | 0 | |
| eqAcuerdo | tinyint(4) | YES | | NULL | |
| idEntidad | int(11) | YES | | NULL | |
| eqFallaECM | tinyint(4) | YES | | 0 | |
+-----------------------+------------------+------+-----+---------+-------+
我觉得这个表(由触发器引用),可能是相关的也:
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-workbench发送查询时触发器触发,而不是每当通过yii(与两个DB模式托管在同一服务器中)发送时触发。我已经看到了以下内容:
MySQL的触发器仅SQL语句激活。它们不会被API所做的表中的更改所激活,这些API不会将SQL语句传送到MySQL服务器;特别是,它们不会被使用NDB API进行的更新激活。
任何帮助或指导是高度赞赏。提前致谢。
编辑: Yii使用PDO来执行插入/更新语句,并且插入被成功反映,更新仍然失败。
使用同一用户进行调试:它在工作台上工作,它从命令行cliend运行,它不能从yii工作。 我不熟悉那个unix(是它的unix?)命令,但我手动检查db.log,发现很多select查询(对应于fk参考验证等,一切顺利)... – Snivs
只有更新日志中的行是这样的: '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 WHERE“tbl_device”。“Id”= 670。绑定:yp0 = 670,:yp1 ='ADSF564ASD9F132CX1',::yp2 ='ReciénLlegado',:yp3 = 12,:yp4 = 5,:yp5 = NULL,:yp6 = 11,:yp7 ='123',: yp8 ='AD3F48C135',:yp9 = NULL,:yp10 ='Skywave',::yp11 ='没有Establecido',::yp12 ='2012-10-29 15:33:37'' – Snivs
而且没有其他重要行,只需选择验证和相关的记录格式显示。这些更改没有反映到主模式,所以我猜'shadow.tbl_device'上的'shadow.trg_device_after_update_reflect_changes'显然没有激活.. – Snivs