2009-03-19 14 views
38

El código es el siguiente:resultados de SQL dinámico en tabla temporal en SQL procedimiento almacenado

ALTER PROCEDURE dbo.pdpd_DynamicCall 
@SQLString varchar(4096) = null 

AS 

Begin 

    create TABLE #T1 (column_1 varchar(10) , column_2 varchar(100)) 

    insert into #T1 
     execute ('execute ' + @SQLString) 

    select * from #T1 

End 

El problema es que yo quiero llamar a diferentes procedimientos que pueden dar vuelta distintas columnas. Por lo tanto, tendría que definir la tabla # T1 genéricamente. Pero no sé cómo.

¿Alguien me puede ayudar con este problema?

+1

sonido como usted debe dejar de tratar de utilizar procedimientos almacenados y utilizar viejas secuencias de comandos SQL parametrizadas lisos. –

Respuesta

34

Probar:

SELECT into #T1 execute ('execute ' + @SQLString) 

Y esto huele muy mal como una vulnerabilidad de inyección SQL.


corrección (por comentario de @ CarpeDiem):

INSERT into #T1 execute ('execute ' + @SQLString) 

también, omitir el 'execute' si la cadena SQL es algo distinto de un régimen

+0

¡Respuesta difícil de aceptar, no puedo hacer que esto funcione! Primero se queja de que no hay * después de SELECT. Y cuando lo puse, se queja de que no hay una tabla para seleccionar. SELECCIONAR * INTO #tmp_input EXECUTE ('SELECCIONAR 1 AS'); >>> Error de la base de datos del servidor SQL: debe especificar una tabla para seleccionar. ¡En SQL Server 2005! – ercan

+3

Creo que la respuesta fue * INSERT * en # T1 execute ('execute' + @SQLString) ... –

+3

No funciona ... – sreejithsdev

0

No estoy seguro si entiendo bien, pero ¿podría formar la instrucción CREATE dentro de una cadena y luego ejecutar esa cadena? De esta forma, podría agregar tantas columnas como desee.

+0

pero, no sé columnas, es dinámico. – Dhana

31

Puede definir una tabla dinámica simplemente a medida que lo inserta dinámicamente, pero el problema está en el alcance de las tablas temporales. Por ejemplo, este código:

DECLARE @sql varchar(max) 
SET @sql = 'CREATE TABLE #T1 (Col1 varchar(20))' 
EXEC(@sql) 
INSERT INTO #T1 (Col1) VALUES ('This will not work.') 
SELECT * FROM #T1 

devolverá con el error "Nombre de objeto no válido '# T1'." Esto se debe a que la tabla temporal # T1 se crea en un "nivel inferior" que el bloque de código de ejecución. Con el fin de solucionar, utilizar una tabla temporal global:

DECLARE @sql varchar(max) 
SET @sql = 'CREATE TABLE ##T1 (Col1 varchar(20))' 
EXEC(@sql) 
INSERT INTO ##T1 (Col1) VALUES ('This will work.') 
SELECT * FROM ##T1 

Espero que esto ayude, Jesse

+0

de hecho, me ayudó. ¡gracias! – user219628

+2

¡Esto es todo! ¡Ahora puedo crear la tabla dentro de mi procedimiento almacenado, con el nombre pasado a través de un argumento! ¡Si pudiera dar 10 votos! –

14

Tenga cuidado de una solución global tabla temporal ya que esto puede fallar si dos usuarios utilizan la misma rutina al mismo tiempo como una tabla temporal global puede ser visto por todos los usuarios ...

7
INSERT INTO #TempTable 
EXEC(@SelectStatement) 
0
DECLARE @EmpGroup INT =3 , 
     @IsActive BIT=1 

DECLARE @tblEmpMaster AS TABLE 
     (EmpCode VARCHAR(20),EmpName VARCHAR(50),EmpAddress VARCHAR(500)) 

INSERT INTO @tblEmpMaster EXECUTE SPGetEmpList @EmpGroup,@IsActive 

SELECT * FROM @tblEmpMaster 
8

crear una tabla temporal global con un GUID en el nombre de forma dinámica. Entonces puede trabajar con él en su código, vía dyn sql, sin preocuparse de que otro proceso que llame a Same Sproc lo use. Esto es útil cuando no sabes qué esperar de la tabla seleccionada subyacente cada vez que se ejecuta, por lo que no puedes crear una tabla temporal explícitamente de antemano. es decir, - es necesario utilizar SELECT * EN sintaxis

DECLARE @TmpGlobalTable varchar(255) = 'SomeText_' + convert(varchar(36),NEWID()) 

-- select @TmpGlobalTable 

-- build query 
    SET @Sql = 
     'SELECT * INTO [##' + @TmpGlobalTable + '] FROM SomeTable' 
EXEC (@Sql) 
EXEC ('SELECT * FROM [##' + @TmpGlobalTable + '] ') 
EXEC ('DROP TABLE [##' + @TmpGlobalTable + ']') 
PRINT 'Dropped Table ' + @TmpGlobalTable 
+0

Si tiene nombres de columna dinámicos, este es el camino a seguir. – jbd

+0

Buena solución. Tenga en cuenta los corchetes alrededor del nombre de la tabla: NEWID convertido a varchar contiene "-" que de lo contrario no son válidos en los nombres de los objetos. – SebTHU

0
CREATE PROCEDURE dbo.pdpd_DynamicCall 
AS 
DECLARE @SQLString_2 NVARCHAR(4000) 
SET NOCOUNT ON 
Begin 
    --- Create global temp table 
    CREATE TABLE ##T1 (column_1 varchar(10) , column_2 varchar(100)) 

    SELECT @SQLString_2 = 'INSERT INTO ##T1(column_1, column_2) SELECT column_1 = "123", column_2 = "MUHAMMAD IMRON"' 
    SELECT @SQLString_2 = REPLACE(@SQLString_2, '"', '''') 

    EXEC SP_EXECUTESQL @SQLString_2 

    --- Test Display records 
    SELECT * FROM ##T1 

    --- Drop global temp table 
    IF OBJECT_ID('tempdb..##T1','u') IS NOT NULL 
    DROP TABLE ##T1 
End 
Cuestiones relacionadas