53 votes

Puis-je passer le nom d'une colonne comme paramètre d'entrée dans une procédure stockée SQL ?

create procedure sp_First
@columnname varchar
AS
begin
select @columnname from Table_1
end 
exec sp_First 'sname'

Mon besoin est de passer des noms de colonnes comme paramètres d'entrée. J'ai essayé comme cela mais cela a donné un résultat erroné.

Aidez-moi

3 votes

Pourriez-vous sélectionner la meilleure réponse à cette question, la première réponse actuelle étant trompeuse.

77voto

MatBailie Points 37610

Vous pouvez le faire de plusieurs manières.

La première consiste à élaborer soi-même la requête et à l'exécuter.

SET @sql = 'SELECT ' + @columnName + ' FROM yourTable'
sp_executesql @sql

Si vous optez pour cette méthode, veillez à bien sanctifier vos données. Même si vous savez que votre application ne donnera que de "vrais" noms de colonnes, que se passe-t-il si quelqu'un trouve une faille dans votre sécurité et est capable d'exécuter le SP directement ? Il peut alors exécuter à peu près tout ce qu'il veut. Avec le SQL dynamique, toujours, toujours valider les paramètres.

Vous pouvez également écrire une instruction CASE...

SELECT
  CASE @columnName
    WHEN 'Col1' THEN Col1
    WHEN 'Col2' THEN Col2
                ELSE NULL
  END as selectedColumn
FROM
  yourTable

C'est un peu plus long, mais beaucoup plus sûr.

12voto

Darren Kopp Points 27704

Non. Cela ne ferait que sélectionner la valeur du paramètre. Vous devez utiliser la méthode sql dynamique.

Dans votre procédure, vous auriez les éléments suivants :

DECLARE @sql nvarchar(max) = 'SELECT ' + @columnname + ' FROM Table_1';
exec sp_executesql @sql, N''

2 votes

Non, pas beaucoup plus lentement. Le seul facteur de ralentissement est la concaténation des chaînes de caractères. sp_executesql exécute le texte de manière à ce qu'il soit traduit en un plan d'exécution, comme n'importe quelle autre commande.

10voto

John Dewey Points 3942

Essayez d'utiliser le SQL dynamique :

create procedure sp_First @columnname varchar 
AS 
begin 
    declare @sql nvarchar(4000);
    set @sql='select ['+@columnname+'] from Table_1';
    exec sp_executesql @sql
end 
go

exec sp_First 'sname'
go

6voto

usr Points 74796

Ce n'est pas possible. Il faut soit utiliser du SQL dynamique (dangereux), soit une gigantesque expression de cas (lente).

0 votes

Si le CASE se trouve uniquement dans l'instruction SELECT (et non dans une clause JOIN, WHERE, ORDER BY, etc.), cette option n'est pas si lente que cela.

1 votes

Il extraira toutes les colonnes à chaque fois, quelle que soit la colonne de béton demandée.

2voto

Out Points 597
   Create PROCEDURE USP_S_NameAvilability
     (@Value VARCHAR(50)=null,
      @TableName VARCHAR(50)=null,
      @ColumnName VARCHAR(50)=null)
        AS
        BEGIN
        DECLARE @cmd AS NVARCHAR(max)
        SET @Value = ''''+@Value+ ''''
        SET @cmd = N'SELECT * FROM ' + @TableName + ' WHERE ' +  @ColumnName + ' = ' + @Value
        EXEC(@cmd)
      END

Comme je l'ai essayé, la réponse est exécutée avec succès, mais lors de l'exécution, elle ne donne pas de résultats corrects, alors que la réponse ci-dessus fonctionne bien.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X