11
votes

Comment sélectionner un schéma basé sur une variable?

Considérez: XXX

Cela ne semble pas être valide: MySQL revient avec:

Vous avez une erreur dans votre syntaxe SQL; Vérifiez le manuel qui correspond à votre version MySQL Server pour la syntaxe droite à utiliser près de '@ Refreshdb.`metadata`

Autant que je puisse dire que j'ai bien fait les choses correctement selon la documentation . Pourtant, MySQL dit que ce n'est pas permis. Est-ce une certaine limitation de MySQL (ne permettant pas d'utiliser des variables comme identifiants) ou autre chose?


0 commentaires

3 Réponses :


8
votes

Vous devrez utiliser préparer la déclaration / dynamique SQL pour le faire.

Cet article passe sur ces deux en excellents détails:

http://rpbouman.blogspot.com/2005/11/mysql-5-Prepared-statement-syntax -and.html

Essayez ceci: xxx


3 commentaires

L'instruction Create Table échoue.


Oh, j'ai raté cela, vous devrez également mettre cela dans une déclaration préparée aussi. Je l'ai mis à jour pour mettre la table de création dans une déclaration préparée.


Avec cette correction, ce que vous avez travaille, mais pour toute personne qui a l'intention de mettre en œuvre cela, sachez des considérations de sécurité et de performance. SQL dynamique peut être un peu d'art noir.



4
votes

Documentation STATS:

"Les variables utilisateur peuvent être attribuées une valeur à partir d'un ensemble limité de types de données: entier, décimal, point flottant, chaîne binaire ou non et valeur null"

Vous essayez d'utiliser la variable comme objet. Ceci n'est pas pris en charge.


3 commentaires

Je ne vois pas comment ce qui peut être attribué aux contrôles de variable où la variable peut être utilisée.


Vous l'utilisez comme objet, ce qui implique que la valeur de @refreshdb est un objet de schéma, et non la valeur de chaîne en réalité.


Je te donne à la fois un uppote sur celui-ci. Sans SQL dynamique (Abe nous donne un moyen de le faire avec DSQL), cela ne peut être fait avec la syntaxe de MySQL, et cela est en fait une bonne chose en ce qu'il simplifie les considérations de sécurité et de performance. Pour ceux qui marchent du côté sauvage, il y a dsql.



0
votes

Je vous suggère d'écrire une procédure stockée:

DELIMITER $$
CREATE PROCEDURE (IN DBname varchar(255)
                , IN AKey varchar(255)
                , IN AValue varchar(255))
BEGIN
  DECLARE query VARCHAR(1000);
  -- First check the DBName against a list of allowed DBnames, 
  -- to prevent SQL-injection with dynamic tablenames.

  DECLARE NameAllowed BOOLEAN;
  SELECT 1 INTO NameAllowed WHERE DBName IN ('validDB1','validDB2');
  IF (NameAllowed = 1) THEN BEGIN

  -- DBName is in the whitelist, it's safe to continue.
    SET query = CONCAT('INSERT INTO '
                      ,DBName
                      ,'.MetaData (`key`,`value`) values (?,?));
    -- note the use of parameter placeholders, to prevent SQL-injection.
    PREPARE stmt FROM query;
    EXECUTE stmt USING Akey, AValue;
    DEALLOCATE PREPARE stmt; -- clears the query and its result from the cache.
  END; END IF;
END $$

DELIMITER ;


1 commentaires

Cela échoue à l'instruction Create Table, pas l'insert.