The reason for the problem you are describing (generating a trigger in a doctrine migration) is most likely a problem concerning the delimiter.
Usually in SQL, when importing a larger SQL-file that contains triggers, the statements that generate the trigger look like this:
DELIMITER //
CREATE TRIGGER `MyTrigger` BEFORE DELETE ON `myTable` FOR EACH ROW BEGIN
DELETE FROM anotherTable WHERE pk = OLD.pk;
END//
DELIMITER ;
The "Delimiter //" and "// DELIMITER" commands are necessary to prevent SQL from interpreting the semicolon as the end-token to the CREATE TRIGGER command. It changes the end token temporaily to "//", such that the semicolon after OLD.pk ist interpreted as the end-token to the "DELETE FROM" statement.
This does not work when using the Method "addSql(...)" in your migration. The lines containing "DELIMITER //" and "//DELIMITER" must be ommited and everything works fine.
These commands are not necessary, because addSql always only accepts one single Sql-Statement at a time, such that it is clear that the semicolon belongs a statement in the Begin..End block of the trigger and not to the trigger itself.
The workaround with expode(...) does not work becaus addSql accepts only a string with only one Sql-Statement (and not an array of multiple SQL-statements) and because is does not strip the delimiter-commands before and after the trigger.