[Mysql] Dynamisches SQL in Trigger/Procedure umgehen

olqs

Erfahrenes Mitglied
Hallo,
ich hab hier eine kleine Datenbank aus 3 Tabellen (erstmal als Text, weiter unten als SQL):
In der users Tabelle werden die Benutzernamen gespeichert.
In der allowed_user_properties werden alle möglichen Eigenschaften gespeichert.
Die Tabelle user_properties verknüpft die beiden oberen Tabellen (m:n) und hängt noch ein Attribut an diese. Damit werden Eigenschaften einem User zugeordnet.

Desweiteren hab ich eine Stored Procedure create_master_view geschrieben, die mir über dynamisches SQL einen View erstellt, um auf diese Struktur zugreifen zu können, als wäre es eine Tabelle. Ist für pam_mysql und andere Anbindungen leider nicht zu umgehen.

Um nicht jedes Mal create_master_view aufrufen zu müssen, wenn man in die allowed_user_properties Tabelle etwas eingefügt hat, wollte ich einen Trigger erstellen der das für mich erledigt.

Jetzt erhalte ich aber nach einem Insert in die allowed_user_properties Tabelle folgende Fehlermeldung:
Code:
ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger

Wie kann ich das dynamische SQL hier umgehen, oder wird mir nichts anderes übrigbleiben, das nicht zu vergessen?

Ach ja hier noch die SQL Anweisungen:
SQL:
/*
Tabellen Definitionen
*/

CREATE TABLE `allowed_user_properties` (
  `pk_aup` int(11) NOT NULL auto_increment,
  `description` varchar(255) NOT NULL,
  `system_property` tinyint(1) default NULL,
  PRIMARY KEY  (`pk_aup`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

CREATE TABLE `user_properties` (
  `pk_up` int(11) NOT NULL auto_increment,
  `fk_aup` int(11) NOT NULL,
  `fk_users` int(11) NOT NULL,
  `value` blob,
  PRIMARY KEY  (`pk_up`),
  KEY `fk_aup` (`fk_aup`),
  KEY `fk_users` (`fk_users`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE `users` (
  `pk_users` int(11) NOT NULL auto_increment,
  `username` varchar(255) NOT NULL,
  PRIMARY KEY  (`pk_users`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

/*
Mit Daten füllen
*/

INSERT INTO `allowed_user_properties` VALUES (1,'password',1),(2,'clear_pass',1);

INSERT INTO `user_properties` VALUES (1,2,1,'test');

INSERT INTO `users` VALUES (1,'olqs');

/*
Stored Procedure create_master_view
*/

DELIMITER $$

CREATE PROCEDURE create_master_view()
        BEGIN
        DECLARE done INT DEFAULT 0;
        DECLARE propertyname varchar(50);
        DECLARE cur1 CURSOR FOR SELECT DISTINCT description FROM system_general.allowed_user_properties WHERE description IS NOT NULL;
        DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;
        OPEN cur1;

        set @sql_string = 'SELECT users.username';

        REPEAT
        FETCH cur1 INTO propertyname;

        IF NOT done THEN

        set propertyname = replace(propertyname, '''', '''''');


        SET @tmp_sql = concat(',
                        ',
                        'MAX(CASE WHEN description = ''',
                        propertyname,
                        ''' THEN value ELSE '''' END) AS ''',
                        propertyname,
                        '''');

        set @sql_string = concat(@sql_string,@tmp_sql);

END IF;

UNTIL done END REPEAT;

CLOSE cur1;

SET @sql_string = concat(@sql_string,'
                from users
                left join user_properties on pk_users = fk_users
                left join allowed_user_properties on fk_aup = pk_aup
                group by username');

drop view if exists master_view;

set @stmt_text=concat('create view master_view as ',@sql_string);
PREPARE stmt FROM @stmt_text;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

END;
$$

DELIMITER ;


/*
Trigger für die allowed_user_properties tabelle
*/

DELIMITER $$

CREATE TRIGGER `allowed_user_properties_after_insert` AFTER INSERT
ON `allowed_user_properties`
  FOR EACH ROW begin
   call create_master_view;
 end:
$$

DELIMITER ;

Die Ausgabe von "select * from master_view" liefert in diesem Beispiel:
Code:
+----------+----------+------------+
| username | password | clear_pass |
+----------+----------+------------+
| olqs     |          | test       |
+----------+----------+------------+
 
Zurück