2012-04-10 5 views

Antwort

5

Dies ist nicht möglich. Verwenden Sie entweder dynamisches SQL (gefährlich) oder einen riesigen Fallausdruck (langsam).

+0

Wenn der CASE nur in der SELECT-Anweisung (und nicht in einer JOIN, WHERE-Klausel, ORDER BY, usw.) ist, ist diese Option nicht wirklich so langsam. – MatBailie

+1

Es wird alle Spalten jedes Mal herausziehen, egal welche konkrete Spalte angefordert wird. – usr

9

Nein. Das würde nur den Parameterwert auswählen. Sie müssten dynamische SQL verwenden.

In Ihrem Verfahren würden Sie haben die folgend:

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

muss es langsamer sein, oder? Aber wieviel? kann es ignoriert werden? –

+1

Nein, nicht viel langsamer. Die einzige Menge, um die es langsamer geht, ist der String-Verkettungs-Overhead. sp_executesql führt den Text so aus, dass er genau wie jeder andere Befehl in einen Ausführungsplan übersetzt wird. –

2

Sie können die Spaltennamen passieren, aber man kann es nicht in einem SQL-statemnt verwenden wie

Select @Columnname From Table 

Man könnte ein dynamisches SQL-Zeichenfolge aufbauen und führen Sie es wie EXEC (@SQL)

Für weitere Informationen finden Sie diese Antwort auf dynamische SQL.

Dynamic SQL Pros and Cons

8

Versuchen dynamische SQL verwenden:

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

Sie diese Art und Weise in ein paar tun können.

Eins, ist die Abfrage selbst aufzubauen und auszuführen.

Wenn Sie sich für diese Methode entscheiden, vergewissern Sie sich sehr, Ihre Eingabe zu sanieren. Selbst wenn Sie wissen, dass Ihre Anwendung nur "echte" Spaltennamen liefert, was ist, wenn jemand Ihre Sicherheit verletzt und den SP direkt ausführen kann? Dann können sie fast alles ausführen, was sie wollen. Mit Dynamic SQL immer immer validieren Sie die Parameter.

Alternativ können Sie eine CASE-Anweisung schreiben ...

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

Das ist ein bisschen mehr langatmig, aber eine ganze Menge mehr sicher.

+9

+1, 'Dies ist ein bisschen mehr umständlich, aber eine ganze Menge sicherer." –

+0

Wenn Sie die Spalten von einer anderen Tabelle "UpdateableColumns" bekommen, können Sie auch eine Art der Verifikation damit tun. Beispiel: "Wo Spalte existiert in (wählen ColumnName von UpdateableColumns)" – EduLopez

-5

Bitte versuchen Sie es mit diesem. Ich hoffe, es wird für Sie arbeiten.

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

Wählen Sie * ist keine gute Praxis und das ist nicht die Zweifel des Benutzers – 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 

Als ich eine Antwort versucht haben, wird es erfolgreich ausgeführt zu werden, aber während seiner nicht geben korrekte Ausgabe läuft, sind die oben genannten Arbeiten gut

0

Wie MatBailie erwähnt Dies ist viel sicherer Da es sich nicht um eine dynamische Abfrage handelt, sind die Chancen auf eine SQL-Injektion geringer. Ich habe eine Situation hinzugefügt, in der die where-Klausel sogar dynamisch sein soll. XX YY sind Spalten Namen

  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 
Verwandte Themen