Je ne parle pas de faire un "SET NOCOUNT OFF". Mais j'ai une procédure stockée que j'utilise pour insérer des données dans certaines tables. Cette procédure crée une chaîne de réponse xml, laissez-moi vous donner un exemple:
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
J'ai donc mis en place un script qui utilise cela SP un tas de fois, et la "sortie" xml devient trop (il a déjà planté ma boîte une fois)).
Existe-t-il un moyen de supprimer ou de rediriger la sortie générée à partir de cette procédure stockée? Je ne pense pas que la modification de cette procédure stockée soit une option.
merci.
Je suppose que je devrais clarifier. Ce SP ci-dessus est appelé par un script de mise à jour T-SQL que j'ai écrit, à exécuter via le gestionnaire de studio d'entreprise, etc.
Et ce n'est pas non plus le SQL le plus élégant que j'ai jamais écrit (certains pseudo-sql):
WHILE unprocessedRecordsLeft
BEGIN
SELECT top 1 record from updateTable where Processed = 0
EXEC insertSomeData @param = record_From_UpdateTable
END
Disons donc que l'UpdateTable contient quelque 50 000 enregistrements. Cela SP est appelé 50k fois, en écrivant des chaînes xml 50k dans la fenêtre de sortie. Cela n'a pas arrêté le serveur sql, juste mon application client (sql server management studio).
Je pense avoir trouvé a une solution.
Donc, ce que je peux faire maintenant dans mon script SQL est quelque chose comme ça (code 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
Maintenant, s'il y avait un moyen encore plus efficace de le faire. SQL Server a-t-il quelque chose de similaire à/dev/null? Une table nulle ou quelque chose?
La réponse que vous cherchez se trouve dans une similaire SO question de Josh Burke:
-- Assume this table matches the output of your procedure
DECLARE @tmpNewValue TABLE ([Id] int, [Name] varchar(50))
INSERT INTO @tmpNewValue
EXEC ProcedureB
SELECT * FROM @tmpNewValue
Répondre à la question "Comment supprimer la sortie de procédure stockée?" dépend vraiment de ce que vous essayez d'accomplir. Je veux donc apporter ma contribution:
J'avais besoin de supprimer la sortie de la procédure stockée (USP) parce que je voulais juste le nombre de lignes (@@ ROWCOUNT) de la sortie. Ce que j'ai fait, et cela peut ne pas fonctionner pour tout le monde, c'est que ma requête étant déjà un SQL dynamique, j'ai ajouté un paramètre appelé @silentExecution à l'USP en question. C'est un paramètre de bit que j'ai par défaut mis à zéro (0).
Ensuite, si @silentExecution était défini sur un (1), j'insérerais le contenu de la table dans une table temporaire, ce qui supprimerait la sortie et exécuterait ensuite @@ ROWCOUNT sans problème.
Exemple 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
Ensuite, vous pouvez exécuter le tout comme ceci:
EXEC dbo.usp_SilentExecutionProc @silentExecution = 1;
SELECT @@ROWCOUNT;
Le but de le faire comme ceci est si vous avez besoin de l'USP pour pouvoir renvoyer un jeu de résultats dans d'autres utilisations ou cas, mais que vous ne l'utilisez que pour les lignes.
Je voulais juste partager ma solution.
Mec, c'est sérieusement le cas d'un ordinateur faisant ce que vous lui avez dit de faire au lieu de ce que vous vouliez faire.
Si vous ne voulez pas qu'il renvoie des résultats, alors ne le faites pas demander pour renvoyer des résultats. Refactorisez cette procédure stockée en deux:
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
À partir de quel client appelez-vous la procédure stockée? Dites que c'était de C #, et vous l'appelez comme:
var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
var read = com.ExecuteReader();
Cela ne récupérera pas encore le résultat du serveur; vous devez appeler Read () pour cela:
read.Read();
var myBigString = read[0].ToString();
Donc, si vous n'appelez pas Read, le XML ne quittera pas le serveur SQL. Vous pouvez même appeler la procédure avec ExecuteNonQuery:
var com = myConnection.CreateCommand();
com.CommandText = "exec insertSomeData 1";
com.ExecuteNonQuery();
Ici, le client ne demandera même pas le résultat de la sélection.
J'ai récemment rencontré un problème similaire lors de l'écriture d'un script de migration et comme le problème a été résolu d'une manière différente, je veux l'enregistrer. J'ai presque tué mon client SSMS en exécutant une boucle while simple pendant 3000 fois et en appelant une procédure.
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
Le résultat du script a été exécuté à l'aide de SSMS et l'option par défaut dans la fenêtre de requête est définie pour afficher "Résultats vers la grille" [raccourci Ctrl + d].
Solution facile: Essayez de définir les résultats dans un fichier pour éviter que la grille soit construite et peinte sur le client SSMS. [Raccourci clavier CTRL + MAJ + F pour définir les résultats de la requête dans un fichier].
Ce problème est lié à: requête stackoverflow
Vous pouvez créer une procédure stockée SQL CLR qui l'exécute. Ça devrait être assez facile.
Vous avez dit que votre serveur plante. Qu'est-ce qui plante l'application qui consomme la sortie de ce SQL ou SQL Server lui-même (en supposant que SQL Server).
Si vous utilisez l'application .Net Framework pour appeler la procédure stockée, consultez SQLCommand.ExecuteNonQuery. Cela exécute simplement la procédure stockée sans aucun résultat renvoyé. Si le problème est au niveau de SQL Server, vous devrez faire quelque chose de différent (c'est-à-dire changer la procédure stockée).
Je ne sais pas si SQL Server a une option pour supprimer la sortie (je ne pense pas que ce soit le cas), mais l'Analyseur de requêtes SQL a une option (sous l'onglet Résultats) pour "Supprimer les résultats".
Exécutez-vous cela via isql?