StackOverflow の皆さん、こんにちは。私はこのサイトのファンで、数え切れないほどの穴から助けてくれました。しかし、今回はここでも他の場所でも答えが見つからないようです。私の問題は次のとおりです。
データベース内のデータを処理し、一貫性とすべてを維持するための Yii Framework アプリケーションを開発しています。基本的には、DB 情報を操作するためのインターフェイスを作成しています。MySQL 5.0 (5.5 への更新予定) と InnoDB を使用しています。
私の開発は、いくつかの設計上の問題がある既存のスキーマ (私はそれを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 への変更を反映するためのトリガーです。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 (2 つの DB スキーマと同じサーバーでホストされている) 経由で送信されるときはいつでも起動しません。私は以下を見てきました:
MySQL トリガーは、SQL ステートメントによってのみアクティブ化されます。これらは、SQL ステートメントを MySQL サーバーに送信しない API によって行われたテーブルの変更によってアクティブ化されません。特に、NDB API を使用して行われた更新によってアクティブ化されません。
ヘルプやガイドラインは大歓迎です。前もって感謝します。
編集: Yii は PDO を使用して挿入/更新ステートメントを実行し、挿入は正常に反映されますが、更新は引き続き失敗します。