web-dev-qa-db-fra.com

Puis-je passer le nom de la colonne en tant que paramètre d'entrée dans un SQL stocké? Procédure

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

Mon exigence est de transmettre les noms de colonne en tant que paramètres d'entrée. J'ai essayé comme ça mais ça a donné une mauvaise sortie.

Alors aide moi

28
user1169809

Vous pouvez le faire de plusieurs manières.

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

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

Si vous optez pour cette méthode, assurez-vous de faire votre entrée. Même si vous savez que votre application ne donnera que des noms de colonne "réels", que se passe-t-il si quelqu'un trouve une faille dans votre sécurité et est capable d'exécuter directement le SP? Ensuite, ils peuvent exécuter à peu près tout ce qu'ils veulent. Avec le SQL dynamique, toujours, toujours , validez les paramètres.

Alternativement, vous pouvez é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.

51
MatBailie

Cela ne ferait que sélectionner la valeur du paramètre. Vous auriez besoin d'utiliser SQL dynamique.

Dans votre procédure, vous auriez ce qui suit:

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

Essayez d'utiliser du 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
9
John Dewey

Ce n'est pas possible. Utilisez du SQL dynamique (dangereux) ou une casse gigantesque (lente).

6
usr
   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 s’exécute avec succès, mais lorsqu’il est en cours d’exécution, cela ne donne pas le résultat correct 

2
Out

Vous pouvez passer le nom de la colonne mais vous ne pouvez pas l’utiliser dans un état SQL comme 

Select @Columnname From Table

On pourrait construire une chaîne SQL dynamique et l'exécuter comme EXEC (@SQL)

Pour plus d'informations, voir cette réponse sur SQL dynamique.

Les avantages et inconvénients de SQL dynamique

2
Jon Raynor

Comme mentionné par MatBailie .__, ceci est beaucoup plus sûr car ce n’est pas une requête dynamique et il y a moins de chances que ce soit une injection SQL. J'ai ajouté une situation dans laquelle vous souhaitez même que la clause where soit dynamique. XX YY sont des noms de colonnes 

            CREATE PROCEDURE [dbo].[DASH_getTP_under_TP]
    (
    @fromColumnName varchar(10) ,
    @toColumnName varchar(10) , 
    @ID varchar(10)
    )
    as
    begin

    -- this is the column required for where clause 
    declare @colname varchar(50)
    set @colname=case @fromUserType
        when 'XX' then 'XX'
        when 'YY' then 'YY'
        end
        select SelectedColumnId  from (
       select 
            case @toColumnName 
            when 'XX' then tablename.XX
            when 'YY' then tablename.YY
            end as SelectedColumnId,
        From tablename
        where 
        (case @fromUserType 
            when 'XX' then XX
            when 'YY' then YY
        end)= ISNULL(@ID , @colname) 
    ) as tbl1 group by SelectedColumnId 

    end
0
Saronyo