2012-05-24 11 views
5

¿Es posible pasar el nombre de la tabla como parámetro de entrada al procedimiento almacenado?Pasando el nombre de la tabla en el procedimiento almacenado sql

Por ejemplo:

create procedure test 
@tablename char(10) 
as 
begin 
select * from @tablename 
end 
go 

Sé que esto no funciona. Entonces, ¿cuál es la mejor manera si quiero pasar el nombre de la tabla al procedimiento almacenado?

Muchas gracias

Respuesta

10

la forma más segura de hacer esto es a través de una vista.

Cree una vista que unifica todas las tablas a las que desea acceder (y que deben tener todas la misma estructura de columnas), y prefija las filas con el nombre de la tabla.

CREATE VIEW MultiTable 
AS 
    SELECT 'table1' AS TableName, * FROM table1 
    UNION ALL 
    SELECT 'table2' AS TableName, * FROM table2 
    UNION ALL 
    SELECT 'table3' AS TableName, * FROM table3 

Su procedimiento almacenado ahora puede filtrar por el nombre de tabla:

CREATE PROCEDURE test 
    @TableName varchar(100) 
AS 
    SELECT * FROM MultiTable WHERE TableName = @TableName 

Esto es más seguro que el uso de SQL dinámico de creación y ejecución.

+0

Muchas gracias. – gunnerz

+1

Se debe tener en cuenta que, al usar "*", el ejemplo supone que las tres tablas tienen el mismo número de columnas. Creo que obtendrías un error de lo contrario. Incluso si este fuera el caso, como una buena práctica, probablemente debería enumerarlos en cada SELECCIÓN. – Buggieboy

+0

@Buggieboy tal vez obtener ese error si las columnas son cambios en solo una de las tablas vale la pena ........ –

3

Debería usar SQL dinámico, pero debe tener en cuenta los posibles riesgos de inyección de sql que se abren como si @tablename contuviera algo dudoso, podría terminar en un mundo de dolor.

p. Ej.

-- basic check to see if a table with this name exists 
IF NOT EXISTS(SELECT * FROM sys.tables WHERE name = @tablename) 
    RETURN 

DECLARE @sql NVARCHAR(100) 
SET @sql = 'SELECT * FROM ' + QUOTENAME(@tablename) 
EXECUTE(@sql) 

Debe tener mucho cuidado con este enfoque, asegúrese de no abrir una lata de gusanos de seguridad.

Mi otra preocupación es que puede estar tratando de hacer sprocs genéricos de acceso a datos, que generalmente es una mala idea. Obviamente no sé tu caso de uso.

+1

[El tuyo es el caso número uno!] (Http://www.sommarskog.se/dynamic_sql. html # Common_cases) – Bridge

+0

Muchas gracias. Hay una posibilidad casi insignificante de inyección sql porque no hay una entrada de usuario para el nombre de la tabla. La aplicación solo lo usa internamente, y quiero evitar la creación de varios archivos almacenados con la misma lógica, excepto los diferentes nombres de tabla – gunnerz

+1

@Bridge. Sí, estoy totalmente de acuerdo. En los casos en que realmente necesitaba usar un nombre de tabla dinámica, personalmente he generado el SQL en el código de la aplicación. Pero no es frecuente que haya encontrado un caso de uso genuino – AdaTheDev

2
DECLARE @Name VARCHAR(50) 
SET @Name='Company' 

EXEC('SELECT * from ' + @Name) 

utilizan esta forma para obtener el registro de la base de datos.

Cuestiones relacionadas