procedimientos - procedimiento almacenado sql server ejemplo
¿Cómo suprimir la salida SELECT de un procedimiento almacenado llamado desde otro procedimiento almacenado en SQL Server? (10)
¿Desde qué cliente está llamando al procedimiento almacenado? Digamos que fue de C #, y lo llamas así:
var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
var read = com.ExecuteReader();
Esto aún no recuperará el resultado del servidor; tienes que llamar a Read () para eso:
read.Read();
var myBigString = read[0].ToString();
Entonces, si no llama a Read, el XML no dejará el servidor SQL. Incluso puede llamar al procedimiento con ExecuteNonQuery:
var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
com.ExecuteNonQuery();
Aquí el cliente ni siquiera pedirá el resultado de la selección.
No estoy hablando de hacer un "SET NOCOUNT OFF". Pero tengo un procedimiento almacenado que utilizo para insertar algunos datos en algunas tablas. Este procedimiento crea una cadena de respuesta xml, así que déjame darte un ejemplo:
CREATE PROCEDURE [dbo].[insertSomeData] (@myParam int) AS
DECLARE @reply varchar(2048)
... Do a bunch of inserts/updates...
SET @reply = ''<xml><big /><outputs /></xml>''
SELECT @reply
GO
Así que armé un script que usa este SP un montón de veces, y el "resultado" del XML está llegando a ser demasiado (una vez ya se estrelló mi caja).
¿Hay alguna forma de suprimir o redirigir la salida generada a partir de este procedimiento almacenado? No creo que modificar este procedimiento almacenado sea una opción.
Gracias.
Supongo que debería aclarar. Este SP anterior está siendo llamado por un script de actualización de T-SQL que escribí, para ejecutarlo a través de Enterprise Studio Manager, etc.
Y tampoco es el SQL más elegante que he escrito (algunos psuedo-sql):
WHILE unprocessedRecordsLeft
BEGIN
SELECT top 1 record from updateTable where Processed = 0
EXEC insertSomeData @param = record_From_UpdateTable
END
Así que digamos que el UpdateTable tiene unos 50k registros en él. A ese SP se le llama 50k veces, escribiendo 50k cadenas xml en la ventana de salida. No detuvo el servidor SQL, solo mi aplicación cliente (estudio de administración del servidor SQL).
Creo que encontré una solución.
Entonces, lo que puedo hacer ahora en mi script SQL es algo como esto (código sql-psuedo):
create table #tmp(xmlReply varchar(2048))
while not_done
begin
select top 1 record from updateTable where processed = 0
insert into #tmp exec insertSomeData @param=record
end
drop table #tmp
Ahora si hubiera una manera aún más eficiente de hacer esto. ¿SQL Server tiene algo similar a / dev / null? ¿Una mesa nula o algo así?
Hombre, esto es en serio el caso de una computadora que hace lo que le dijiste que hiciera en lugar de lo que querías que hiciera.
Si no desea que devuelva resultados, no le pida que devuelva resultados. Refactorizar ese procedimiento almacenado en dos:
CREATE PROCEDURE [dbo].[insertSomeData] (@myParam int) AS
BEGIN
DECLARE @reply varchar(2048)
--... Do a bunch of inserts/updates...
EXEC SelectOutput
END
GO
CREATE PROCEDURE SelectOutput AS
BEGIN
SET @reply = ''<xml><big /><outputs /></xml>''
SELECT @reply
END
La respuesta que estás buscando se encuentra en una pregunta similar de SO por Josh Burke:
/* Assume this table matches the output of your procedure */
DECLARE @tmpNewValue TABLE (newvalue int)
INSERT INTO @tmpNewValue
EXEC ProcedureB
No sé si SQL Server tiene una opción para suprimir la salida (no creo que la tenga), pero el Analizador de consultas SQL tiene una opción (debajo de la pestaña de resultados) para "Descartar resultados".
¿Está ejecutando esto a través de isql?
Podría crear un procedimiento almacenado de CLR de SQL que ejecute esto. Debería ser bastante fácil.
Recientemente me he topado con un problema similar al escribir un script de migración y, como el problema se resolvió de otra manera, quiero registrarlo. Casi he matado a mi cliente SSMS ejecutando un bucle while simple 3000 veces y llamando a un procedimiento.
DECLARE @counter INT
SET @counter = 10
WHILE @counter > 0
BEGIN
-- call a procedure which returns some resultset
SELECT @counter-- (simulating the effect of stored proc returning some resultset)
SET @counter = @counter - 1
END
El resultado del script se ejecutó usando SSMS y la opción predeterminada en la ventana de consulta está configurada para mostrar "Resultados a la cuadrícula" [Ctrl + d atajo].
Solución fácil: intente establecer los resultados en el archivo para evitar que la cuadrícula se construya y se pinte en el cliente SSMS. [Atajo de teclado CTRL + MAYÚS + F para establecer los resultados de la consulta en el archivo].
Este problema está relacionado con: query
Respondiendo a la pregunta "¿Cómo suprimo la salida del procedimiento almacenado?" Realmente depende de lo que está tratando de lograr. Así que quiero aportar lo que encontré:
Necesitaba suprimir la salida del procedimiento almacenado (USP) porque solo quería el recuento de filas (@@ ROWCOUNT) de la salida. Lo que hice, y esto puede que no funcione para todos, es que como mi consulta ya iba a ser dinámica sql, agregué un parámetro llamado @silentExecution a la USP en cuestión. Este es un parámetro de bit que por defecto es cero (0).
A continuación, si @silentExecution se configuró en uno (1) insertaría el contenido de la tabla en una tabla temporal, que es lo que suprimiría la salida y luego ejecutaría @@ ROWCOUNT sin ningún problema.
Ejemplo de USP:
CREATE PROCEDURE usp_SilentExecutionProc
@silentExecution bit = 0
AS
BEGIN
SET NOCOUNT ON;
DECLARE @strSQL VARCHAR(MAX);
SET @strSQL = '''';
SET @strSQL = ''SELECT TOP 10 * '';
IF @silentExecution = 1
SET @strSQL = @strSQL + ''INTO #tmpDevNull '';
SET @strSQL = @strSQL +
''FROM dbo.SomeTable '';
EXEC(@strSQL);
END
GO
Entonces puedes ejecutar todo así:
EXEC dbo.usp_SilentExecutionProc @silentExecution = 1;
SELECT @@ROWCOUNT;
El propósito de hacerlo de esta manera es si necesita que la USP pueda devolver un conjunto de resultados en otros usos o casos, pero que lo utilice solo para las filas.
Solo quería compartir mi solución.
Usted dijo que su servidor está fallando. Qué es lo que bloquea la aplicación que consume la salida de este SQL o el mismo SQL Server (asumiendo que se trata de SQL Server).
Si está utilizando la aplicación .Net Framework para llamar al procedimiento almacenado, eche un vistazo a SQLCommand.ExecuteNonQuery. Esto solo ejecuta el procedimiento almacenado sin resultados devueltos. Si el problema está en el nivel de SQL Server, tendrá que hacer algo diferente (es decir, cambiar el procedimiento almacenado).
alguna vez intente SET NOCOUNT ON;
¿como una opción?