2012-04-10 24 views

Trả lời

5

Điều này là không thể. Sử dụng SQL động (nguy hiểm) hoặc biểu thức trường hợp khổng lồ (chậm).

+0

Nếu CASE chỉ trong câu lệnh SELECT (và không phải trong mệnh đề JOIN, WHERE, ORDER BY, v.v.) thì tùy chọn này không thực sự chậm. – MatBailie

+1

Nó sẽ rút ra tất cả các cột mỗi lần, bất kể cột bê tông nào được yêu cầu. – usr

9

No. Điều đó sẽ chỉ chọn giá trị tham số. Bạn sẽ cần phải sử dụng sql động.

Trong thủ tục của bạn, bạn sẽ có những điều sau đây:

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

nó phải chậm hơn, phải không? nhưng bao nhiêu? nó có thể bị bỏ qua không? –

+1

Không, không chậm hơn nhiều. Số tiền duy nhất nó chậm hơn là chi phí nối chuỗi. sp_executesql sẽ thực hiện văn bản theo cách nó sẽ được dịch sang một kế hoạch thực hiện giống như bất kỳ lệnh nào khác. –

2

Bạn có thể vượt qua các tên cột nhưng bạn không thể sử dụng nó trong một statemnt sql như

Select @Columnname From Table 

Người ta có thể xây dựng một chuỗi sql động và thực hiện nó như EXEC (@SQL)

Để biết thêm thông tin, hãy xem câu trả lời này trên sql động.

Dynamic SQL Pros and Cons

8

Hãy thử sử dụng SQL động:

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

Bạn có thể làm điều này trong một vài cách khác nhau.

Một, là tự mình xây dựng truy vấn và thực thi nó.

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

Nếu bạn chọn phương pháp đó, hãy chắc chắn để santise đầu vào của bạn. Ngay cả khi bạn biết ứng dụng của bạn sẽ chỉ cung cấp cho các tên cột 'thực', điều gì xảy ra nếu ai đó tìm thấy một vết nứt trong bảo mật của bạn và có thể thực thi SP trực tiếp? Sau đó, họ có thể thực hiện bất cứ thứ gì họ thích. Với SQL động, luôn luôn, luôn luôn, xác thực thông số.

Ngoài ra, bạn có thể viết một tuyên bố CASE ...

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

Đây là một chút dài hơn hơi, nhưng một tổng thể nhiều an toàn hơn.

+9

+1, 'Cái này dài hơn một chút, nhưng an toàn hơn rất nhiều.' –

+0

Nếu bạn nhận được các cột từ một bảng" UpdateableColumns "khác, bạn cũng có thể thực hiện một số loại xác minh với nó. Ví dụ: "Vị trí Cột tồn tại trong (chọn ColumnName từ UpdateableColumns)" – EduLopez

-5

Hãy thử với điều này. Tôi hy vọng nó sẽ làm việc cho bạn.

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

Chọn * không phải là phương pháp hay và điều này không phải là sự nghi ngờ của người dùng – 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 

Như tôi đã thử một câu trả lời, đó là nhận được thực hiện thành công nhưng khi chạy không đưa ra sản lượng chính xác của nó, các công trình trên cũng

0

Như đã đề cập bởi MatBailie Đây là nhiều hơn nữa an toàn vì nó không phải là một truy vấn động và có ít cơ hội tiêm sql hơn. Tôi đã thêm một tình huống mà bạn thậm chí muốn mệnh đề where là động. XX YY là các tên Cột

  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 
Các vấn đề liên quan