2013-09-22 4 views
1

J'essaie de porter sur un concept que j'utilise dans le code Java que j'ai utilisé pour les procédures stockées SQL et je ne suis pas sûr que ce soit possible. Essentiellement, si j'ai une table avec 10 colonnes, je veux être capable de mettre à jour différentes combinaisons de colonnes de la même procédure stockée à chaque fois. C'est à dire. en Java, je transmettais une carte contenant les valeurs que je voulais mettre à jour et je les parcourais et je mettais à jour chaque valeur de clé dans le cache. Ceci a l'avantage de ne pas avoir à changer la signature de la méthode pour inclure chaque nom de colonne et de ne pas avoir besoin d'un gros morceau de code pour effectuer une vérification nulle sur chaque variable pour savoir si elle doit être mise à jour ou non. Je ne sais pas si c'est possible ou si certains serveurs de base de données en sont capables (c'est-à-dire PostgreSQL, Oracle, MySQL) ou s'ils sont tous capables de le faire mais je n'arrive pas à comprendre la syntaxe.Mettre à jour différentes colonnes dans une procédure stockée

+0

Pouvez-vous publier un exemple de code Java pour que vous compreniez mieux ce que vous essayez d'obtenir. – calcinai

+0

Cela peut être fait en utilisant SQL dynamique dans l'un des SGBD que vous avez mentionné. –

Répondre

1

Dans SQL Server, la procédure ci-dessous fonctionnerait en supposant une table comme ceci:

CREATE TABLE MyBigTable(
    ID INT NOT NULL PRIMARY KEY, 
    COLUMNA VARCHAR(100) NOT NULL, 
    COLUMNB VARCHAR(100) NOT NULL 
) 

GO 

CREATE PROCEDURE UpdateMyBigTable(@ID INT, @ColumnAValue VARCHAR(100)=NULL, @ColumnBValue VARCHAR(100)=NULL) 
AS BEGIN 
UPDATE MyBigTable 
    SET COLUMNA = CASE WHEN @ColumnAValue IS NULL THEN COLUMNA ELSE @ColumnAValue END, 
    COLUMNB = CASE WHEN @ColumnBValue IS NULL THEN COLUMNB ELSE @ColumnBValue END 
WHERE ID = @ID 
    AND ((COLUMNA <> @ColumnAValue AND @ColumnAValue IS NOT NULL) OR (COLUMNB <> @ColumnBValue AND @ColumnBValue IS NOT NULL)); 
END 

GO 

Cependant, cela ne fait pas énumèrent à travers les champs qui est ce que vous demandez au sujet. C'est difficile à faire dans SQL Server sans entrer dans le SQL dynamique.

+1

Dans le second cas, comment faites-vous la distinction entre une colonne que vous voulez définir comme NULL et une colonne dont vous ne voulez pas modifier la valeur? –

+0

Vous avez raison. Je vais retirer ça. La solution devient beaucoup plus complexe si vous autorisez les valeurs nulles parce que je suppose que vous devriez entrer dans des valeurs interdites telles que l'envoi de caractères ASCII bas. Lors de la relecture, l'une ou l'autre solution ne fonctionne pas vraiment pour le cas déclaré par les OP, ce qui demande un moyen de boucler les colonnes. – NYCdotNet

+0

Si vous faites cela, vous mettez à jour réellement les valeurs - même si avec sa propre valeur existante. De mémoire, cela provoque le recalcul des index, donc est plus lent que de trouver une déclaration conditionnelle au début. –

0

Pour de meilleures performances, utilisez SQL dynamique ou une instruction IF avec une instruction SQL pour chaque combinaison possible de paramètres de requête.

Si vous pouvez faire les déclarations IF pour chaque solution possible, optez pour cela - c'est stable, sécurisé et performant.

Si vous avez trop de paramètres pour cela, utilisez SQL dynamique - vous pouvez générer votre SQL dynamique dans la procédure stockée ou plus tôt, assurez-vous simplement d'éviter SQL injection issues.

Votre problème est très similaire au problème dynamic search couvert par Erland Sommarskog. En ce qui concerne les performances, SQL Server créera un plan d'exécution pour chaque type de requête dynamique possible, de sorte que les performances seront aussi bonnes que d'avoir une instruction IF pour sélectionner chaque instruction SQL possible. Ceci est en contraste frappant avec l'utilisation de COLUMNB = CASE WHEN @COLUMNB IS NULL THEN COLUMNB ELSE @COLUMNB END qui aura un seul plan d'exécution et donc souvent un plan d'exécution médiocre (en fonction de votre clause where et de ses index dans la base de données) et une performance médiocre.

Questions connexes