Bonjour,

Voila je rencontre un petit problème avec mon code.

Ce que je fais

voila , j'ai deux table onlines(id,client,ip) et aides(id,motif,date,commentaire)
j'aimerai que lorsqu'on a une nouvelle entrée dans la table onlines, que j'ai automatiquement une insertion dans la table aides. voici ce que je fait

CREATE DEFINER = CURRENT_USER TRIGGER `mybd`.`onlines_AFTER_INSERT` AFTER INSERT ON `onlines` FOR EACH ROW
BEGIN
insert into aides(id,motif,date,commentaire) value('','aide',SYSDATE(),'dfgdfgdffffgf');
END

Ce que je veux

je veux que la table aides soit mise à jour automatiquement par le trigger

Ce que j'obtiens

Error: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'id' at row 1
je parcours bien ma table onlines mais le type de champ id est un INT auto increment la preuve lorsque je supprimer bien le trigger de la table je peux faire des insertions directement dans phpmyadmin ou en ligne de commande, mais si j'ajoute le trigger l'erreur survient

quequ'un a une idée? SVP

26 réponses


Pierrot01
Réponse acceptée

tu changes INT par DATETIME

@plus

romses
Auteur

personne n'a encore eu ce problème?

insert into aides(id,motif,date,commentaire) value(NULL,'aide',SYSDATE(),'dfgdfgdffffgf');

@plus

romses
Auteur

Merci pierrot01, la valeur de mon champ id est un auto increment , je constate la tu as mis NULL???

oui, tu met null ou tu ne le met pas.
insert into aides(motif,date,commentaire) value('aide',SYSDATE(),'dfgdfgdffffgf');
ou
insert into aides(id,motif,date,commentaire) value(NULL,'aide',SYSDATE(),'dfgdfgdffffgf');

romses
Auteur

oui je l'ai essaye mai rien

mais rien quoi ?

romses
Auteur

la même erreur
Error: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'id' at row 1

Bonjour,

tu es bien sur mysql?

Ensuite on parle bien de valeur NULL pas vide ('') .
Enfin quelle est la raison qui pousse à passer par un trigger?

romses
Auteur

Suis sur MYSQL
oui je parle de la valeur NULL,
j'ai essayer de faire une insertion directement dans le phpmyadmin voici le code insert into aides(id,motif,date,commentaire) value(NULL,'aide',SYSDATE(),'dfgdfgdffffgf'); et toujours la même erreur
Error: SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'id' at row 1

Mais si je supprime le trigger et que recrèe la table tous ce passe bien.

j'ai comme l'impression mysql ne digère pas facilement les trigger.

Voici laraison pour la quelle je veux utiliser les trigger
déjà ça m'est venu en tête comme une solution dire je ne suis pas expert en mysql ou php.

je suis entrain de développer une application ou je gère les prets des clients, et lorsque un client effectue un pret je dois calculer directement le montant de rembourssement à l'echeance et aussi les interets .Il existe plusieurs type de prets et en fonction de chaque type les opérations de calculs varient.

Donc la solution j'ai eu est de déporter tout la logique ducôté de la base de donnée c'est a dire que lorsque un client effectu un pret, que les interets et opérations soient faites directement du côté de la base de donnée mais vous pouvez m'en proposer autre si possible car je reste ouvert à tous vos conseils.

SVP

montre moi le create table de cette table ?

On est bien d'accord que dans le trigger tu insère rien dans l'id de la table aide?

romses
Auteur

oui antho07 puisque mon champ id est auto increment

romses
Auteur

voici mon create table

CREATE TABLE `onlines` (
  `id` int(11) NOT NULL,
  `client` varchar(255) DEFAULT NULL,
  `poste` varchar(255) DEFAULT NULL,
  `created` datetime DEFAULT CURRENT_TIMESTAMP,
  `profile_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Contenu de la table `onlines`

-- Déclencheurs `onlines`
--
DELIMITER $$
CREATE TRIGGER `onlines_AFTER_INSERT` AFTER INSERT ON `onlines` FOR EACH ROW BEGIN
insert into aides(type_aide,delai,montant_participation,created,caisse_cotisation_id) value('aide',SYSDATE(),'20000',SYSDATE(),'12');
END
$$
DELIMITER ;
romses
Auteur

Salut, Résolu
Merci à tout vos suggestions vraiment merci encore j'ai du réinstallé Mysql et tout va à merveille je ne sais pas ce qui s'était passé mais bon pour le moment je suis à la ligne.

Maitenant j'ai une
Est ce que c'est la meilleure solution d'otomatisé tous les calculs des emrpunts dans la Base de donnée? car jusqu'ici c'est la seule solution j'ai puisque pour chaque type de pret, les calculs des intérets sont différents et le calcul pénalités aussi

Pour ma part,
le trigger est plutôt utile quand sur une même base plusieurs applications communiquent et que des traitements doivent être déclenchés pour synchroniser des tables , créer des objets en réactions à une insertion à tel endroit etc.

Une autre raison pourrait également être la performance. Selon l'architecture du systèmes, des traitements peuvent être déportés en base pour limiter des échanges réseaux trop lourd, mais personnellement je ne l'envisage qu'en derniers recours, et ceux pour plusieurs raisons :

Les triggers, procédures, fonctions vont être destinés à un SGBD particulier. En cas de changement de SGBD, la migration ne sera pas automatique et une énorme partie devra être recodée , avec tous les risques de régressions, les charges de tests et de développements associés. Par ailleurs, dans un contexte de maintenance, le dévleoppeur en charge de la correction d'une anomalie se dirigera avant tout vers le code de l'application sur un bug applicatif, avec les documentations qui se perdent au fur et à mesure de la vie d'un projet, il risque de passer un peu de temps avant de comprendre que les traitements sont déclenchés directement en base.
Le débug ne sera pas facilité non plus.
Enfin il y a également un risque que tout ceci devienne au fil des années et de l'évolution du besoin à un gros sac de noeud en base.
Ainsi, le moindre ajout de traitement en base demandera un effort d'analyse en plus pour identifier les impacts. Le risque de chaîne de trigger qui forme une boucle devra être observé chaque fois.
Et pour finir le traitement des erreurs, la journalisation, sera compliqué. Pour tracer un bug , il faudra analyser la partie du traitement faîte par le codede l'application, puis celui en base.

Bien entendu cette avis n'engage que moi et sans doute que d'autres exposeront des points de vue différents

"Bien entendu cette avis n'engage que moi et sans doute que d'autres exposeront des points de vue différents"
oui, le mien est totalement different

@plus

romses
Auteur

Merci Pierrot01, mais dans mon cas tu meconseillerai quoi?vu que j'ai des traitement qui sont délenchés par des action biens précises et en plus plusieurs tables vont entrées en jeux dans l'execution. sans oublier que nous aurions plus de 100 utilisateurs connectés.

alors doit faire mes opérations côté applicative ou dans la base de donnée?

j'ai donné mon avi au dessus ;)
@plus

Bonjour à tous,

Si l'avis d'un vieux peut vous intéresser et aussi vous aider à trouver une voie alors je vous la donne.

Depuis plusieurs années, il existe un débat entre les défenseurs du Base de Données First et les Code First.

Pour ma part je suis de la vieille école, donc du BDD first. Je pars du principe que les instructions de la partie applicatives doivent être les plus petites et laisser le serveur de base de données effectuer ses propres procédures.
Pour moi il est préférable de passer par des triggers ou des procédures stockées lors de manipulations de données dans la base. En plus, s'il apparait des erreurs tu peux effectuer des RollBack et revenir à l'état initial.
En terme de sécurité, c'est plus propre

Mais évidemment, cela implique d'avoir dans une équipe de dev, un ou plusieurs membres avec de bonne connaissances en BDD, ce qui peut être difficile et cher à trouver.

Quoiqu'il en soit, ton choix dépend aussi de la taille de ta BDD et de l'importance des données concervées. Si tu n'as que quelques dixaines de tables ou que l'aspect économique des données sont faibles alors mieux vaut opter pour un "Code First".
Par contre, si ta base contient plusieurs centaines de tables ( actuellement je travaille sur une base d'un peu plus de 800 tables), ou avec plusieurs bases en simultanées, avec des milliers d'insertions, modifications etc.. de données alors là mieux vaut opter pour une BDD first.

Et puis je ne suis pas complètement persuadé que la migration d'une BDD bien construite en SQL-server, postgreSQL, Oracle soit plus couteuse en temps que de migrer un gros projet Symphony en Cake voir en ruby, Node ou C#.

Je ne sais pas si mon avis a pu faire un peu avancer le smilblick.

Bonne journée à vous

moi, j'aime bien l'avis des vieux :D

romses
Auteur

Ok Merci pour l'avis des Vieux je me lance aussi même comme je sais j'aurais beaucoup à apprendre la.
Bon déjà comme je vous l'ai dit je ne suis pas expert en Procédure stocquée mais j'apprends vite.

Voila le code qe j'ai dans mon trigger :

delimiter //
CREATE DEFINER = CURRENT_USER TRIGGER `association`.`onlines_AFTER_INSERT` AFTER INSERT ON `onlines` FOR EACH ROW
BEGIN

SELECT MAX(date_init) INTO boucle FROM `initialisations` WHERE DATE(date_init) = CURRENT_DATE;
IF (boucle = 1) THEN 
INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'1','24');
ELSE 
INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'2','24');
END IF;
END //
delimiter ;

voici l'erreur cela me génère:

Executing SQL script in server
ERROR: Error 1415: Not allowed to return a result set from a trigger
SQL Code:
        CREATE DEFINER = CURRENT_USER TRIGGER `association`.`onlines_AFTER_INSERT` AFTER INSERT ON `onlines` FOR EACH ROW
        BEGIN

        SELECT MAX(date_init) as boucle FROM `initialisations` WHERE DATE(date_init) = CURRENT_DATE;
        IF (boucle = 1) THEN 
        INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'1','24');
        ELSE 
        INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'2','24');
        END IF;
        END 

SQL script execution finished: statements: 7 succeeded, 1 failed

Fetching back view definitions in final form.
Nothing to fetch

j'avoue je suis unpeu perdu quelqu'un peut avoir une idée?
SVP

DECLARE boucle int;
SET boucle = (SELECT MAX(date_init) as boucle FROM initialisations WHERE DATE(date_init) = CURRENT_DATE);

y a quand même qqchose que je comprend pas.

c'est le IF

Si vrai fait sinon fait quand même

@plus

romses
Auteur

Merci Pierrot01,

pour le if je sais c'est juste d'exemple c'est pas l'instruction qui sera executé.
Par contre voici la modif je viens de faire

delimiter |
CREATE DEFINER = CURRENT_USER TRIGGER `association`.`onlines_AFTER_INSERT` AFTER INSERT ON `onlines` FOR EACH ROW
 BEGIN
DECLARE boucle int;
        set boucle = (SELECT MAX(date_init) as boucle FROM `initialisations` WHERE DATE(date_init) = CURRENT_DATE);
        IF (boucle = 1) THEN 
        INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'1','24');
        ELSE 
        INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'2','24');
        END IF;
        END |

après exécution , j'ai l'erreur suivante:
Error: SQLSTATE[01000]: Warning: 1265 Data truncated for column 'boucle' at row 3

romses
Auteur

Merci Pierrot01 ça marche nickel se sont mes premiers pas dans le trigger je ferrais l'effort de beaucoup en apprendre d'avantage quand j'imagine des tas de truc on peut faire avec les scripts cotés SGBD. Merci encore
@plus

romses
Auteur

Merci déjà pour vos réactions, mais j'ai encore un autre soucis
en effet j'ai créer ma procédure stocqué suivante

CREATE PROCEDURE totalecheanceparuser()
BEGIN
DECLARE boucle int;
        set boucle = (SELECT MAX(statut) as boucle FROM `initialisations` WHERE DATE(date_init) = CURRENT_DATE);
        IF (boucle = 30) THEN 
        INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'10','24');
        ELSE 
        INSERT INTO initialisations(date_init,statut,profile_id) VALUES(SYSDATE(),'30','24');
        END IF;
END 

et dans la table onlines j'ai créer un déclencheur après insertion dont voici le code:

delimiter |
CREATE DEFINER = CURRENT_USER TRIGGER `association`.`onlines_AFTER_INSERT` AFTER INSERT ON `onlines` FOR EACH ROW
 BEGIN
CALL totalecheqsdqdsanceparuserd();
END |

tous ce passe bien seulement si je met le l'appel de la procédure en commentaite ça fonctionne toujours

soit ceci:

delimiter |
CREATE DEFINER = CURRENT_USER TRIGGER `association`.`onlines_AFTER_INSERT` AFTER INSERT ON `onlines` FOR EACH ROW
 BEGIN
/*CALL totalecheqsdqdsanceparuserd();*/
END |

mon problème est de savoir comment je peux mettre ma fonction en commentaire mais tous fonctionne toujours? je veux dire lorsque je fais mon insertion ma procédure est toujours lancé .

SVP