Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

Alternativa a Insert Exec Anidado

Estas en el tema de Alternativa a Insert Exec Anidado en el foro de SQL Server en Foros del Web. Buen día, Tengo un procedimiento almacenado que me devuelve cierta cantidad columnas (dicha cantidad depende de los ciertas consultas) y en este, utilizo la instrucción ...
  #1 (permalink)  
Antiguo 07/02/2012, 08:55
Avatar de AWesker  
Fecha de Ingreso: octubre-2008
Mensajes: 177
Antigüedad: 16 años, 1 mes
Puntos: 27
Alternativa a Insert Exec Anidado

Buen día,
Tengo un procedimiento almacenado que me devuelve cierta cantidad columnas (dicha cantidad depende de los ciertas consultas) y en este, utilizo la instrucción EXECUTE sp_executesql @Variable para hacer un insert en una tabla Temporal, ya que es de vital importancia que lo utilice en este método.

Me han pedido que presente los resultados como una sola matriz. Por supuesto acudí a Internet y encontré que utilizando una tabla temporal mediante INSERT #Temp EXEC SP_ABC @ParametroX, @ParametroY. Es importante decir que como las columnas no estan definidas, debo crear las columnas de forma dinámica utilizando nuevamente el EXEC sp_executesql. Pero al probar el procedimiento almacenado completo me aparece el error: "La instrucción INSERT EXEC no se puede anidar".

Intenté crear una función con valores de tabla pero no he podido plantear la forma de hacerla.

Ojalá tengan sugerencias. Saludos...
  #2 (permalink)  
Antiguo 07/02/2012, 09:16
Avatar de Andres95
Colaborador
 
Fecha de Ingreso: diciembre-2004
Mensajes: 1.802
Antigüedad: 19 años, 11 meses
Puntos: 38
Respuesta: Alternativa a Insert Exec Anidado

Podrias poner un ejemplo de la sintaxis que te marca el error..

los siguientes funcionan en SQL 2008...

Código:
if OBJECT_ID('tempdb..#tmpUno') is not null drop table #tmpUno

create table #tmpUno (id int identity (1,1), valor VARCHAR(10))


INSERT INTO #tmpUno
execute (' 
select ''primero''
')

INSERT INTO #tmpUno 
execute ('
execute sp_executesql N''SELECT ''''segundo'''' '' 
')

alter table #tmpUno add  otraColumn varchar(10) not null default('')

execute ('INSERT INTO #tmpUno(valor, otraColumn) 
execute sp_executesql N''SELECT ''''tercero'''', ''''dato3'''' '' 
')

select * from #tmpUno

---------------------------------------------------------
Resultado!

id          valor      otraColumn
----------- ---------- ----------
1           primero    
2           segundo    
3           tercero    dato3

Solo como comentario, por experiencia propia evitamos el uso de alter tables para generar resultados de tablas con columnas dinamicas..

Lo mejor es regresar la informacion segun su estructura de dominio original y es en el lado del cliente (aplicacion o servicio de reporte) en donde se le da la vista o el formato requerido por el usuario..

esto te libera muchos recursos en tu servidor sql y el formateo del lado del cliente (aplicacion) es mucho mas eficiente y rapido...



Saludos!
__________________
La sencillez y naturalidad son el supremo y último fin de la cultura...
--
MCTS : SQL Server 2008, .NET Framework 3.5, ASP.NET Applications.

Última edición por Andres95; 07/02/2012 a las 09:24
  #3 (permalink)  
Antiguo 07/02/2012, 10:26
Avatar de AWesker  
Fecha de Ingreso: octubre-2008
Mensajes: 177
Antigüedad: 16 años, 1 mes
Puntos: 27
Respuesta: Alternativa a Insert Exec Anidado

Gracias por responder Andres95

En cuanto a las columnas dinámicas, en realidad es un pivot y este me devuelve las columnas (por cierto, abrí este tema porque no encontraba solución). Que por cierto, se convierte en el primer execute sp_executesql.

Esto es lo que hace el primer procedimiento (SP_ABC):
Código SQL:
Ver original
  1. --Por si ha quedado en memoria por algún error
  2. IF OBJECT_ID('tempdb..##Tmp_001') IS NOT NULL
  3. BEGIN
  4.     DROP TABLE ##Tmp_001
  5. END
  6.  
  7. @SentenciaSQL = N'SELECT * FROM (ABC) AS PIV PIVOT Sum(Monto) FOR ....'
  8.  
  9. --Primer uso de EXECUTE (asumiendo que ya la tabla ##Tmp_001 ya esta en memoria
  10. INSERT INTO ##Tmp_001 EXEC(@SentenciaSQL)
  11.  
  12. --Después hago inner join con esta tabla temporal (##Tmp_001) ya que debo presentar otros datos:
  13. SELECT * FROM (
  14.    SELECT X FROM ABC...
  15. )AS Qry LEFT JOIN ##Tmp_001
  16. ON Qry.Codigo = ##Tmp_001.Codigo

Esto es lo que hace el segundo procedimiento
Código SQL:
Ver original
  1. --Verificando si ya existe la tabla
  2. IF OBJECT_ID('tempdb..##Tmp_002') IS NOT NULL
  3. BEGIN
  4.     DROP TABLE ##Tmp_002
  5. END
  6.  
  7. --Aquí voy a traer las columnas utilizando [B]parte[/B] de la lógica del pivot
  8. @SentenciaTmp = N'CREATE TABLE ##Tmp_002'
  9. --Aquí me genera el error:
  10. INSERT #Tmp_002 EXEC SP_ABC @Parametro01, @Parametro02
  11.  
  12. --Después continua una rutina de eliminación de la tabla

Gracias por el tiempo...
  #4 (permalink)  
Antiguo 07/02/2012, 10:41
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 18 años, 3 meses
Puntos: 774
Respuesta: Alternativa a Insert Exec Anidado

y porque no lo haces directamente desde tu "query dinamico"

Código SQL:
Ver original
  1. SET @query='insert into ##temp2 select blabla bla'
  2. EXECUTE sp_executesql @query
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #5 (permalink)  
Antiguo 07/02/2012, 11:50
Avatar de AWesker  
Fecha de Ingreso: octubre-2008
Mensajes: 177
Antigüedad: 16 años, 1 mes
Puntos: 27
Respuesta: Alternativa a Insert Exec Anidado

Gracias por la sugerencia Libras,
dejame ver si te entendí: me dices que solamente utilice un solo procedimiento almacenado y que este inserte en la tabla temporal 2 los detalles. De ser así, creo que caigo en lo mismo. Y al intentar modificar el procedimiento me genera error:
Código SQL:
Ver original
  1. INSERT INTO ##Tmp_02
  2.    SELECT * FROM (
  3.       SELECT X FROM ABC...
  4.    )AS Qry LEFT JOIN ##Tmp_001
  5.    ON Qry.Codigo = ##Tmp_001.Codigo

Me dice sintaxis incorrecta cerca de ")"

y creo que siempre tendría que anidar el INSERT INTO ##Tmp_x

¿O me planteas otra alternativa?

Se te agradece el tiempo...
  #6 (permalink)  
Antiguo 07/02/2012, 13:06
Avatar de Andres95
Colaborador
 
Fecha de Ingreso: diciembre-2004
Mensajes: 1.802
Antigüedad: 19 años, 11 meses
Puntos: 38
Respuesta: Alternativa a Insert Exec Anidado

Cita:
y creo que siempre tendría que anidar el INSERT INTO ##Tmp_x
asi es, lo mejor es que el insert into este en el mismo nivel de anidamiento que el select correspondiente..

si te fijas en mi ejemplo, creando la tabla al primer nivel la puedes usar igual anidada a un segundo nivel...

solo un ojo con la definicion de las temporales, tu estas usando globales (##) y tal vez lo que buscas es que sean por sesion o locales (#)...

Tablas temporales locales y globales


Saludos!
__________________
La sencillez y naturalidad son el supremo y último fin de la cultura...
--
MCTS : SQL Server 2008, .NET Framework 3.5, ASP.NET Applications.
  #7 (permalink)  
Antiguo 08/02/2012, 08:42
Avatar de AWesker  
Fecha de Ingreso: octubre-2008
Mensajes: 177
Antigüedad: 16 años, 1 mes
Puntos: 27
Respuesta: Alternativa a Insert Exec Anidado

Gracias Libras, gracias Andres95. Con sus aportes logré obtener los resultados en la misma tabla sin errores. La solución fue hacer el insert en el mismo procedimiento almacenado. De esta forma obvié el otro procedimiento y obtuve los datos que necesitaba.

Saludos...

Etiquetas: exec, insert, tabla, anidados
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 19:17.