2012-04-10 21 views
21
create procedure sp_First 
@columnname varchar 
AS 
begin 
select @columnname from Table_1 
end 
exec sp_First 'sname' 

Mi requisito es pasar los nombres de las columnas como parámetros de entrada. Lo intenté así pero me dio una salida incorrecta.Puedo pasar el nombre de la columna como parámetro de entrada en SQL almacenado Procedimiento

Así me ayuda

+3

puede por favor seleccionar la mejor respuesta a esta pregunta, la primera respuesta actual es engañosa. – ctbrown

Respuesta

5

Esto no es posible. Utilice SQL dinámico (peligroso) o una expresión de caso gigantesca (lenta).

+0

Si el CASO está solo en la instrucción SELECT (y no en una cláusula JOIN, WHERE, ORDER BY, etc.) entonces esta opción no es realmente tan lenta. – MatBailie

+1

Extraerá todas las columnas cada vez, sin importar qué columna de concreto se solicite. – usr

9

No. Eso solo seleccionaría el valor del parámetro. Necesitarías usar sql dinámico.

En su procedimiento tendría la siguiente:

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

debe ser más lento, ¿verdad? ¿Pero cuanto? puede ser ignorado? –

+1

No, no mucho más lento. La única cantidad por la que es más lento es la sobrecarga de concatenación de cadena. sp_executesql ejecutará el texto de forma que se traduzca en un plan de ejecución como cualquier otro comando. –

2

puede pasar el nombre de la columna pero no se puede utilizar en un statemnt sql como

Select @Columnname From Table 

Uno podría construir una cadena SQL dinámico y ejecutarlo como EXEC (@SQL)

Para obtener más información, consulte esta respuesta en sql dinámico.

Dynamic SQL Pros and Cons

8

Trate de usar SQL dinámico:

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

Usted puede hacer esto en un par de maneras.

Una, es crear la consulta usted mismo y ejecutarla.

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

Si optas por ese método, asegúrate de santificar tu información. Incluso si sabe que su aplicación solo dará nombres de columna 'reales', ¿qué pasa si alguien encuentra una grieta en su seguridad y puede ejecutar el SP directamente? Entonces pueden ejecutar casi cualquier cosa que quieran. Con SQL dinámico, siempre, siempre, valide los parámetros.

Como alternativa, puede escribir una instrucción CASE ...

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

Esto es un poco más largo aliento, pero mucho más seguro.

+9

+1, 'Esto es un poco más largo, pero mucho más seguro. –

+0

Si obtiene las columnas de otra tabla" UpdateableColumns ", también puede hacer algún tipo de verificación con ella. Ejemplo: "Donde existe la columna en (seleccione ColumnName from UpdateableColumns)" – EduLopez

-5

Por favor, intente con esto. Espero que funcione para usted.

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

Seleccionar * no es una buena práctica y estas no son las dudas del usuario – 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 

como he probado uno la respuesta, cada vez es ejecutado con éxito, pero durante la ejecución de su salida correcta no dar, lo anterior funciona así

0

Según lo mencionado por MatBailie Esto es mucho más segura ya que no es una consulta dinámica y hay menos posibilidades de inyección sql. Agregué una situación en la que incluso quieres que la cláusula where sea dinámica. XX YY son nombres de columnas

  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 
Cuestiones relacionadas