¿Cómo suprimir la salida SELECT de un Procedimiento Almacenado llamado desde otro Procedimiento Almacenado en SQL Server?


No estoy hablando de hacer un "SET NOCOUNT OFF". Pero tengo un procedimiento almacenado que uso para insertar algunos datos en algunas tablas. Este procedimiento crea una cadena de respuesta xml, bien permítanme darles 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 la "salida" xml está llegando a ser demasiado (ya se estrelló mi caja una vez).

¿ Hay alguna forma de suprimir o redirigir la salida generada a partir de este procedimiento almacenado? Yo no piense que modificar este procedimiento almacenado es una opción.

Gracias.


Supongo que debo aclarar. Este SP anterior está siendo llamado por un script de actualización de T-SQL que escribí, para ser ejecutado a través de enterprise studio manager, etc.

Y tampoco es el SQL más elegante que he escrito nunca (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 la tabla de actualización tiene unos registros de 50k. Ese SP se llama 50k veces, escribiendo cadenas xml de 50k en la ventana de salida. No trajo el servidor sql a una parada, solo mi aplicación cliente (sql server management studio).

Author: bdukes, 2009-05-15

10 answers

Creo que encontré una solución.

Así que 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 tabla nula o algo así?

 26
Author: Dave Baghdanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-15 16:01:07

La respuesta que estás buscando se encuentra en una similar SO question de Josh Burke:

/* Assume this table matches the output of your procedure */
DECLARE @tmpNewValue TABLE (newvalue int)

INSERT INTO @tmpNewValue 
  EXEC ProcedureB
 26
Author: Serj Sagan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-14 18:22:17

Respondiendo a la pregunta, " ¿Cómo puedo suprimir la salida del procedimiento almacenado?"realmente depende de lo que usted está tratando de lograr. Así que quiero contribuir con 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 no funcionar para todos, es que como mi consulta ya iba a ser sql dinámico agregué un parámetro llamado @silentExecution a la USP en cuestión. Este es un parámetro de bits que por defecto a cero (0).

A continuación, si @silentExecution se establece 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 de la siguiente manera:

EXEC dbo.usp_SilentExecutionProc @silentExecution = 1;
SELECT @@ROWCOUNT;

El propósito detrás de hacerlo así es si necesita que la USP sea capaz de devolver un conjunto de resultados en otros usos o casos, pero aún lo utiliza solo para el filas.

Solo quería compartir mi solución.

 6
Author: dyslexicanaboko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-15 14:22:15

Hombre, este es seriamente un caso de una computadora haciendo lo que le dijiste que hiciera en lugar de lo que tú querías que hiciera.

Si no desea que devuelva resultados, entonces no pida que devuelva resultados. Refactor que almacenó el procedimiento 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
 5
Author: John Saunders,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-15 01:45:16

¿Desde qué cliente está llamando al procedimiento almacenado? Digamos que era de C#, y lo estás llamando 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();

Así que si no llamas a Read, el XML no saldrá del 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.

 2
Author: Andomar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-15 07:48:10

Puede crear un procedimiento almacenado SQL CLR que ejecute esto. Debería ser bastante fácil.

 1
Author: Hafthor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-15 00:52:52

Recientemente me he encontrado con un problema similar al escribir un script de migración y ya que el problema se resolvió de una manera diferente, quiero grabarlo. Casi he matado a mi cliente SSMS ejecutando un bucle while simple durante 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ó utilizando SSMS y la opción predeterminada en la ventana de consulta está configurada para mostrar "Resultados en Cuadrícula"[Ctrl+d acceso directo].

Solución fácil: Trate de establecer los resultados a archivo para evitar la rejilla que se construirá y pintará en el cliente SSMS. [CTRL + SHIFT + F atajo de teclado para establecer los resultados de la consulta en archivo].

Este problema está relacionado con: consulta de stackoverflow

 1
Author: Lin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:46:46

No se si SQL Server tiene una opción para suprimir la salida (no creo que lo haga), pero el Analizador de Consultas SQL tiene una opción (en la pestaña resultados) para "Descartar resultados".

¿Está ejecutando esto a través de isql?

 0
Author: MikeW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-15 00:27:35

Usted dijo que su servidor está fallando. Lo que está bloqueando la aplicación que consume la salida de este SQL o SQL Server en sí (suponiendo 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 es a nivel de SQL Server, entonces usted va a tener que hacer algo diferente (es decir, cambiar el procedimiento almacenado).

 0
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-05-15 01:40:42

¿Alguna vez has probado SET NOCOUNT ON; como una opción?

 -2
Author: plozi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-22 09:34:05