Además de la respuesta bien puesta por Remus, incluido el enlace que proporcionó
Cómo compartir datos entre procedimientos almacenados
Hay situaciones en las que obtiene los siguientes mensajes de error al guardar los resultados de un procedimiento almacenado en una tabla:
Una instrucción INSERT EXEC no se puede anidar.
La transacción actual no se puede confirmar y no puede admitir operaciones que escriben en el archivo de registro. Revertir la transacción
y cuando esto sucede en mis propios procedimientos almacenados que desarrollo para mi propio uso
por ejemplo, una herramienta para distinguirme de login
todos los grupos de AD a los que pertenece y todos sus permisos en todas las bases de datos en un servidor
Creo una tabla temporal fuera del procedimiento y paso su nombre como parámetro
--===============
-- this way below it works, by passing a temp table as a parameter
--===============
if OBJECT_ID('tempdb.dbo.#my_table') IS NOT NULL
DROP TABLE #my_table
CREATE TABLE #my_table(
db nvarchar(128) COLLATE Latin1_General_CI_AS NULL,
permission_type nvarchar(128) COLLATE Latin1_General_CI_AS NULL,
login_ nvarchar(128) COLLATE Latin1_General_CI_AS NULL,
role_ nvarchar(128) COLLATE Latin1_General_CI_AS NULL,
Obj nvarchar(517) COLLATE Latin1_General_CI_AS NULL,
Permission nvarchar(128) COLLATE Latin1_General_CI_AS NULL,
script nvarchar(1008) COLLATE Latin1_General_CI_AS NULL
)
exec sp_GetLoginDBPermissionsX
@Login='my_loginname',
@debug=0,
@where_to_save ='#my_table'
select *
from #my_table
y dentro del procedimiento, después de todos los cálculos, cuando devuelvo los datos finales (debajo de un ejemplo) verifico si estamos enviando a una tabla o simplemente de regreso a la pantalla y creo el script dinámicamente.
select @sql = case when @where_to_save IS not null then
'
insert into ' + @where_to_save + '(db,Permission_Type,login_,role_,obj,Permission,script) '
else '' end +
'
SELECT
J.db,
J.Permission_Type,
J.login_,
J.role_,
J.Obj,
J.Permission,
J.script
FROM #tablewithpermissions J
WHERE J.login_ IN ( SELECT L1.LOGIN_FROM COLLATE Latin1_General_CI_AS FROM #logins L1)
OR J.role_ IN ( SELECT L1.LOGIN_FROM COLLATE Latin1_General_CI_AS FROM #logins L1)
ORDER BY J.DB, J.[permission_order]
'
--print(@sql)
EXEC(@SQL)
Después de eso, tiene la información que necesita en la pantalla, o si ha pasado una tabla temporal como parámetro, tendrá los datos ahora.
Esta es una solución que encontré, pero solo la uso para mis propios trabajos, de lo DBA
contrario, esto se considerará de alto riesgo para la inyección de SQL .