Hello!
Az alábbi triggert szeretném léterhozni mysql-ben:
CREATE TRIGGER mac_trigger AFTER INSERT ON radacct FOR EACH ROW
IF (SELECT COUNT(*) FROM radcheck WHERE ( UserName = NEW.UserName AND Attribute = 'Calling-Station-Id' AND Value = '')) > 0 THEN
UPDATE radcheck SET Value = `NEW.Calling-Station-Id` WHERE (UserName = NEW.UserName AND Attribute = 'Calling-Station-Id')
END IF;
(nem rakom code-ba, mert akkor látszanak a mod_security miatt belerakott
<m>
-ek)
De syntax errot-t kapok. Mit csinálok rosszul?
Annyit szeretnék, hogy ha a radacct táblába beszúrunk egy új rekordot, akkor a radcheck táblában megnézzük, hogy ahol UserName == a radacct-ba beszúrt új sor UserName mezője, és Attribute == 'Calling-Station-Id', ott a Value mező üres-e. Ha üres, akkor szúrjuk be oda a radacct táblába újonnan beszúrt sor Calling-Station-Id mezőjét.
Tudtok nekem segíteni?
Előre is köszönöm!
Petya
- 7205 megtekintés
Hozzászólások
Rakd begin end közé, és használj mási kdelimiter ehhez, valahogy így:
mysql> deli miter //
mysql> CRE ATE TRIGGER mac_trigger AFTER INSERT ON radacct FOR EACH ROW
- > BE GIN
- > IF (SEL ECT COUNT(*) FROM radcheck WHERE ( UserName = NEW.UserName AND Attribute = 'Calling-Station-Id' AND Value = '')) > 0 THEN
- > UPD ATE radcheck SET Value = `NEW.Calling-Station-Id` WHERE (UserName = NEW.UserName AND Attribute = 'Calling-Station-Id')
- > END IF;
- > END;
mysql> //
mysql> deli miter ;
--
The Net is indeed vast and infinite...
http://gablog.eu
- A hozzászóláshoz be kell jelentkezni
mysql> deli miter //
mysql> CRE ATE TRIGGER mac_trigger AFTER INSERT ON radacct FOR EACH ROW
-> BEGIN
-> IF (SE LECT COUNT(*) FROM radcheck WHERE ( UserName = NEW.UserName AND Attribute = 'Calling-Station-Id' AND Value = '')) > 0 THEN
-> UPD ATE radcheck SET Value = `NEW.Calling-Station-Id` WHERE (UserName = NEW.UserName AND Attribute = 'Calling-Station-Id')
-> END IF;
-> END;
-> //
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UPDATE radcheck SET Value = `NEW.Calling-Station-Id` WHERE (UserName = NEW.UserN' at line 4
- A hozzászóláshoz be kell jelentkezni
s/`NEW.Calling-Station-Id`/NEW.`Calling-Station-Id`/
valamint az UPDATE sor végére egy ;
--
The Net is indeed vast and infinite...
http://gablog.eu
- A hozzászóláshoz be kell jelentkezni
Köszönöm, így már elfogadja, viszont nem működik.
Közben mást is javítottam (a RADIUS nem úgy működött, ahogy elsőre gondoltam), tehát a mostani állapot:
DELIMITER //
CRE ATE TRIGGER mac_trigger AFTER INS ERT ON radacct FOR EACH ROW
BEGIN
IF (SEL ECT COUNT(*) FROM radcheck WHERE ( UserName = NEW.UserName AND Attribute = 'Calling-Station-Id')) = 0
THEN INS ERT INTO radcheck (id, UserName, Attribute, op, Value) VALUES ( NULL, NEW.UserName, 'Calling-Station-Id', '==' ,NEW.`CallingStationId`);
END IF;
END;
//
Annyi a változás, hogy nem az üres sort, hanem a sor hiányát kell figyelni, és nem UPD ATE hanem INS ERT van, ha aktiválódik a trigger.
Petya
- A hozzászóláshoz be kell jelentkezni
Hello!
Azt hiszem, megvan a probléma, a triggerben lévő SQL parancsok nem futnak le:
IF ((SE LECT COUNT(*) FROM radcheck WHERE ( UserName = 'triggerteszt' AND Attribute = 'Calling-Station-Id')) = 0 )
THEN INS ERT INTO radcheck (id, UserName, Attribute, op, Value) VALUES ( NULL, 'triggerteszt', 'Calling-Station-Id', '==' ,'proba');
END IF;
Erre megint csak syntax error. Egyáltalán hogy kell a COUNT kimenetét az IF-nek megadni? Erre sehol nem látok leírást, példát.
Petya
- A hozzászóláshoz be kell jelentkezni
Lehet hogy nincs igazam, akkor majd kijavítotok.
Nekem az a tapasztalatom, hogy a MySQL nem fogad el az IF feltételében select-et. Az ilyen nekem csk úgy müxik, hogy a select eredményét változóba rakom, és a változó értékét vizsgálom.
Mondom, lehet hogy én vagyok lammer, de eddig nekem csak imigyen ment.
(Debian "Sarge", Mysql 5.0.51-3)
---
"A megoldásra kell koncentrálni nem a problémára."
- A hozzászóláshoz be kell jelentkezni
Próbáltam, de a DEC LARE-en is leakad.
BE GIN
DEC LARE x INT;
IF ((SE LECT COUNT(*) FROM radcheck IN TO x WHERE ( UserName = 'triggerteszt' AND Attribute = 'Calling-Station-Id')) = 0 )
THEN INS ERT INTO radcheck (id, UserName, Attribute, op, Value) VALUES ( NULL, 'triggerteszt', 'Calling-Station-Id', '==' ,'proba');
END IF;
END;
Vagy esetleg tárolt eljárásban tudok csak változót deklarálni?
szerk: próbálom a tárolt eljárást, de ez sem jó, syntax error:
DELI MITER //
CRE ATE PROC EDURE `mac_proc`(`user` VARCHAR(50), `mac` VARCHAR(50))
BEG IN
DEC LARE `x` INT := NULL;
SE LECT COUNT(*) FROM `radcheck` INTO `x` WHERE ( `UserName` = `user` AND `Attribute` = 'Calling-Station-Id');
IF `x` = 0 THEN IN SERT INTO `radcheck` (`id`, `UserName`, `Attribute`, `op`, `Value`) VALUES ( NULL, `user`, 'Calling-Station-Id', '==' ,`mac`);
END IF;
END;//
Petya
- A hozzászóláshoz be kell jelentkezni
Van ötletetek?
- A hozzászóláshoz be kell jelentkezni
az if-be lévő rész lefut?
próbáld a lekéréseket phpmyadminba
pch
- A hozzászóláshoz be kell jelentkezni
Elfogad.
cre ate trigger tg_szamlakiad_update after up dateon kimszamlacikklista
for each row
begin
if (SEL ECT vont FR OM `kimszamla` where szamla_id=NEW.szamla_id) < 1 then
up date keszlet set menny=menny+NEW.menny-OLD.menny where cikk_id=NEW.cikk_id and raktar_id=NEW.raktar_id;
end if;
end;
itt a szamlazombol egy selectes trigger.
pch
- A hozzászóláshoz be kell jelentkezni
Hello!
Ezt próbáltam legutóbb:
delimiter //
CRE ATE TRIGGER `mac_trig` AFTER INS ERT ON `radacct` FOR EACH ROW
IF ( SEL ECT * FROM `radcheck` WHERE (`UserName` = NEW.`UserName` AND `Attribute` = 'Calling-Station-Id') ) < 1
THEN IN SERT INTO `radcheck` (`id`, `UserName`, `Attribute`, `op`, `Value`)
VALUES ( NULL, NEW.`UserName`, 'Calling-Station-Id', '==' ,NEW.`CallingStationId`);
END IF;
END//
Erre syntax error-t dob, de ennek ellenére a trigger létrejön, de nem működik. Ha kézzel próbálom hívni a triggerben lévő INS ERT-et, akkor is hibát dob (illegal mix of collations for operation =), de a sort beszúrja.
Mi lehet a baj?
Petya
- A hozzászóláshoz be kell jelentkezni
Valakinek van ötlete?
- A hozzászóláshoz be kell jelentkezni
En mondjuk ezt a count(*)-osat lecserelenem egy IF EXISTS-re, mert az amugyis gyorsabb (nem kell vegigmenni az osszes soron ha van benne). Bar ez a hibahoz nem kotodik, tudom.
- A hozzászóláshoz be kell jelentkezni
new.'username' szerintem a ludas. helyesen new.username
pch
- A hozzászóláshoz be kell jelentkezni
Úgy is próbáltam.
De valami akkor sem oké, ugyanis:
mysql> delimiter //
mysql> CRE ATE TRIG GER mac_trig AFTER INS ERT ON radacct FOR EACH ROW
-> IF ( SEL ECT * FROM radcheck WHERE (UserName = NEW.UserName AND Attribute = Calling-Station-Id) ) < 1
-> THEN INSE RT INTO radcheck (id, UserName, Attribute, op, Value)
-> VALUE S ( NULL, NEW.UserName, 'Calling-Station-Id', '==' ,NEW.CallingStationId);
-> END IF;
-> END//
Query OK, 0 rows affected (0.02 sec)
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'END' at line 1
mysql>
Ennek ellenére a trigger létrejön.
Próbálom aktiválni a triggert:
mysql> INS ERT INTO `radacct` ( `RadAcctId` , `AcctSessionId` , `AcctUniqueId` , `UserName` , `Realm` , `NASIPAddress` , `NASPortId` , `NASPortType` , `AcctStartTime` , `AcctStopTime` , `AcctSessionTime` , `AcctAuthentic` , `ConnectInfo_start` , `ConnectInfo_stop` , `AcctInputOctets` , `AcctOutputOctets` , `CalledStationId` , `CallingStationId` , `AcctTerminateCause` , `ServiceType` , `FramedProtocol` , `FramedIPAddress` , `AcctStartDelay` , `AcctStopDelay` )
-> VAL UES (
-> NULL , '', '', 'triggerteszt', '', '', NULL , NULL , '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL , NULL , NULL , NULL , NULL , NULL , '', 'dfgydgdfg', '', NULL , NULL , '', NULL , NULL
-> );
ERROR 1267 (HY000): Illegal mix of collations (utf8_hungarian_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='
mysql>
Itt megtörténik az IN SERT, de a trigger nem fut le.
Petya
- A hozzászóláshoz be kell jelentkezni
Hello!
Megint felhozom, hátha valaki tud segíteni.
mysql> DELIMITER //
mysql> CRE ATE TRIGGER mac_trig AFTER INS ERT ON radacct FOR EACH ROW
-> BEGIN
-> DECLARE cnt int(10);
-> SET cnt = 0;
-> SE LECT id INTO cnt FROM radcheck WHERE (UserName = NEW.UserName AND Attribute = Calling-Station-Id);
-> IF cnt = 0 THEN
-> INS ERT INTO radcheck (id, UserName, Attribute, op, Value)
-> VALUES ( NULL, NEW.UserName, 'Calling-Station-Id', '==' ,NEW.CallingStationId);
-> END IF;
-> END;//
Most már sikerült elérni, hogy a trigger létrehozásakor nincs hibaüzenet, de INS ERT-kor ugyanúgy "illegal mix of collations", és nem fut le a trigger.
Petya
- A hozzászóláshoz be kell jelentkezni
Hát akkor nézd meg, hogy hol különbözik a collation...
(protip: Calling-Station-Id)
--
The Net is indeed vast and infinite...
http://gablog.eu
- A hozzászóláshoz be kell jelentkezni
Próbálkozom, de pontosan melyik collation-knek kell stimmelni?
INS ERT INTO `radacct` ( `RadAcctId` , `AcctSessionId` , `AcctUniqueId` , `UserName` , `Realm` , `NASIPAddress` , `NASPortId` , `NASPortType` , `AcctStartTime` , `AcctStopTime` , `AcctSessionTime` , `AcctAuthentic` , `ConnectInfo_start` , `ConnectInfo_stop` , `AcctInputOctets` , `AcctOutputOctets` , `CalledStationId` , `CallingStationId` , `AcctTerminateCause` , `ServiceType` , `FramedProtocol` , `FramedIPAddress` , `AcctStartDelay` , `AcctStopDelay` )
VALUES (
NULL , '', '', 'triggerteszt', '', '', NULL , NULL , '0000-00-00 00:00:00', '0000-00-00 00:00:00', NULL , NULL , NULL , NULL , NULL , NULL , '', 'asdgsdgsdg', '', NULL , NULL , '', NULL , NULL
)
#1267 - Illegal mix of collations (utf8_hungarian_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='
Maga az adatbázis, és az összes tábla utf8_hungarian_ci-ben van. Az illető két tábla mezői viszont tényleg keverve vannak, az egyikben utf8_hungarian_ci, a másikban pedig utf8_general_ci a mezők collation-je.
Meg lehet ezt változtatni úgy, hogy vannak adatok a táblában? Próbáltam kidumpolni, és a dumpon megadni a mező collation-t, de erre hibát dobott.
Mindennhol utf8_hungarian_ci a collation, ennek ellenére a dump behúzásakor ut8_general_ci-re állnak be a mezők. Honnan veszi ezt a default értéket? Hogyan tudom megváltoztatni?
Petya
- A hozzászóláshoz be kell jelentkezni
Minden szöveges oszlopnak van collationja, és minden adatbázisnak és táblának van default collationje. (Ez adja meg a rendezést a stringeken, pl. magyarban Czirók < Csipek )
phpmyadmin-al könnyen meg tudod változtatni a collation akár oszlopra, akár adatbázisra, egyébként:
ALTER TABLE `my_table` DEFAULT CHARACTER SET latin1 COLLATE latin1_general_ci
ALTER TABLE `my_table` COLLATE utf8-general_ci
Nem biztos, hogy érdemes megváltoztatni, lehet, hogy akkor más fog megborulni:
dinamikusan is castolhatsz egyik collationből a másikba (ez része az attribútum típusának):
SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;
http://dev.mysql.com/doc/refman/5.0/en/charset-convert.html
Az hogy hol van gond - kivételesen - látszik a hibaüzenetből: "="
--
The Net is indeed vast and infinite...
http://gablog.eu
- A hozzászóláshoz be kell jelentkezni
Köszönöm, sikerült megoldani.
Petya
- A hozzászóláshoz be kell jelentkezni
"SELECT CAST(_latin1'test' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin;"
No, ez nekem is jól jött.
Köszi
- A hozzászóláshoz be kell jelentkezni