2012-04-10 10 views

risposta

5

Questo non è possibile. O utilizzare SQL dinamico (pericoloso) o una gigantesca espressione del caso (lenta).

+0

Se CASE è solo nell'istruzione SELECT (e non in una clausola JOIN, WHERE, ORDER BY, ecc.), Questa opzione in realtà non è così lenta. – MatBailie

+1

Ogni volta estrarrà tutte le colonne, indipendentemente dalla colonna di cemento richiesta. – usr

9

No. Ciò dovrebbe selezionare solo il valore del parametro. Dovresti utilizzare SQL dinamico.

Nella procedura si avrebbe la seguente:

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

deve essere più lento, giusto? ma quanto? può essere ignorato? –

+1

No, non molto più lento. L'unica quantità più lenta è il sovraccarico della concatenazione delle stringhe. sp_executesql eseguirà il testo in un modo in cui verrà tradotto in un piano di esecuzione come qualsiasi altro comando. –

2

è possibile passare il nome della colonna, ma non è possibile utilizzare in uno statemnt SQL come

Select @Columnname From Table 

Uno potrebbe costruire una stringa SQL dinamico ed eseguirlo come EXEC (@SQL)

Per ulteriori informazioni vedere questa risposta su sql dinamico.

Dynamic SQL Pros and Cons

8

Provare a utilizzare SQL dinamico:

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

exec sp_First 'sname' 
go 
45

È possibile farlo in un paio di modi.

Uno, è creare la query ed eseguirla.

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

Se si opta per questo metodo, sii assolutamente sicuro di santificare il tuo input. Anche se sai che la tua applicazione fornirà solo nomi di colonne "reali", e se qualcuno troverà una crepa nella tua sicurezza ed è in grado di eseguire direttamente la SP? Quindi possono eseguire quasi tutto ciò che vogliono. Con SQL dinamico, sempre sempre, convalidare i parametri.

In alternativa, è possibile scrivere una dichiarazione CASE ...

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

Questo è un po 'più lungo senza fiato, ma un bel po' più sicuro.

+9

+1, 'Questo è un po 'più lungo, ma molto più sicuro. –

+0

Se stai ottenendo le colonne da un'altra tabella" UpdateableColumns "puoi anche fare un qualche tipo di verifica con esso. Esempio: "Dove esiste la colonna (selezionare ColumnName da UpdateableColumns)" – EduLopez

-5

Si prega di provare con questo. Spero che funzionerà per voi.

Create Procedure Test 
(
    @Table VARCHAR(500), 
    @Column VARCHAR(100), 
    @Value VARCHAR(300) 
) 
AS 
BEGIN 

DECLARE @sql nvarchar(1000) 

SET @sql = 'SELECT * FROM ' + @Table + ' WHERE ' + @Column + ' = ' + @Value 

--SELECT @sql 
exec (@sql) 

END 

-----execution---- 

/** Exec Test Products,IsDeposit,1 **/ 
+0

Seleziona * non è una buona pratica e questo non è i dubbi dell'utente – Tiago

2
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 = ''''[email protected]+ '''' 
     SET @cmd = N'SELECT * FROM ' + @TableName + ' WHERE ' + @ColumnName + ' = ' + @Value 
     EXEC(@cmd) 
     END 

come ho cercato una risposta, è sempre eseguito con successo, ma durante l'esecuzione del corretto uscita non dare, le opere di cui sopra e

0

Come già detto da MatBailie questo è molto più sicura poiché non è una query dinamica e ci sono minori probabilità di iniezione sql. Ho aggiunto una situazione in cui si desidera anche che la clausola where sia dinamica. XX YY sono i nomi delle colonne

  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 
Problemi correlati