Procédure stockée simple et invocation simple dans SQL Server 2014:
CREATE TABLE [dbo].[SEQUENCES] ( [SEQ_NAME] [nvarchar](50) NOT NULL, [SEQ_NEXT_ID] [numeric](11, 0) NOT NULL, [SEQ_INCREMENT] [numeric](2, 0) NOT NULL, CONSTRAINT [SEQ_PK] PRIMARY KEY CLUSTERED ([SEQ_NAME] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] CREATE PROCEDURE [dbo].[SomeStoredProcedure] @SequenceName [NVARCHAR](MAX), @Increment [INT] AS BEGIN UPDATE [dbo].[SEQUENCES] SET SEQ_NEXT_ID = SEQ_NEXT_ID + @Increment OUTPUT deleted.SEQ_NEXT_ID WHERE SEQ_NAME = @SequenceName END BEGIN DECLARE @value NUMERIC(11,0); EXEC @value = SomeStoredProcedure 'FOO', 1; -- 'FOO' already exists in SEQUENCES so we do get a value -- weird results this always prints 0 if we uncomment the return -- statement right below then and only then the correct value is printed PRINT @value; -- RETURN; INSERT INTO SOME_TABLE (ID, NAME) VALUES (@value, -- @value is always zero so we get a PK constraint violation ... 'Something'); END
3 Réponses :
Lorsque vous souhaitez renvoyer certaines valeurs de la procédure stockée, vous devez utiliser des paramètres de sortie.
Par exemple Créer une procédure comme p> puis affecter la valeur correcte au paramètre @Value. p> Pour lire la valeur renvoyée à partir de la procédure stockée Utilisation: p> valeur 0 après exec @value = somestoredprocedure 'foo', 1; code> signifie que la procédure stockée n'a renvoyé aucune erreur. P> p>
Pour que cela soit plus complet, vous devez inclure des détails sur la manière de OP devrait utiliser exécuté code> lorsqu'il y a un paramètre
sortie code>
Question rapide: Seriez-vous assez aimable pour expliquer pourquoi l'instruction d'impression imprime la valeur correcte si nous n'entraînons simplement pas l'instruction «Retour» située sous l'impression? Je ne peux tout simplement pas envelopper ma tête autour de ce comportement bizarre.
L'instruction Imprimer n'imprimera pas la valeur correcte. Mais vous pouvez voir la valeur renvoyée par "Sortie supprimée.seq_next_id" dans le volet Résultat de la requête, vous verrez toujours 0 dans le volet Messages.
Si vous utilisez la syntaxe exec @variable = SP code> puis
@variable code> sera attribué à la valeur code> de retour de code> retournée b> par le SP (c'est pas i> identique à la valeur de l'ensemble de données B> renvoyé par le SP). Un SP, s'il n'a pas de code> Retour code> retournera
0 code> sur le succès; Mme SP renvoie le code d'erreur sur l'échec. Si vous souhaitez mettre la valeur de l'ensemble de données dans une variable, vous devez utiliser une variable de table, @XDS.
Votre processus ne fait rien. Il n'y a pas de paramètre de sortie que je peux voir. Pire encore, vous appelez le code suppose que le processus renvoie une chaîne. Procs renvoie des entiers (codes de retour). P>
Deux choses que vous devez faire: 1. Ajouter une sortie param.
BEGIN DECLARE @value NUMERIC(11,0); EXECUTE SomeStoredProcedure 'FOO', 1, @value OUTPUT; -- 'FOO' already exists in SEQUENCES so we do get a value -- weird results this always prints 0 if we uncomment the return -- statement right below then and only then the correct value is printed --select @value; -- RETURN; INSERT INTO SOME_TABLE (ID,NAME) VALUES ( @value, -- @value is always zero so we get a PK constraint violation ... 'Something'); END
Question rapide: Seriez-vous assez aimable pour expliquer pourquoi l'instruction d'impression imprime la valeur correcte si nous n'entraînons simplement pas l'instruction «Retour» située sous l'impression? Je ne peux tout simplement pas envelopper ma tête autour de ce comportement bizarre.
@Xds Imprimer L'instruction ne fait rien, cette valeur que vous voyez est la sortie de cette procédure stockée. Si vous souhaitez voir la valeur d'instruction d'impression, vous devez cliquer sur l'onglet Message, consultez cet onglet. Vous pouvez voir la valeur d'impression. Vous pouvez trouver un onglet de message à droite de l'onglet Résultat. "- Sortie supprimée.seq_next_id" Il s'agit de la valeur que vous souhaitez imprimer.
Avez-vous des enregistrements en quelque sorte en ce moment? À quoi ressemble l'enregistrement dans des séquences pour FOO en ce moment?
Pour SEQ_NAME = 'FOO', la table de séquences contient SEQ_NEXT_ID = 128. Tout va bien à cet égard. L'incrémentation arrive. C'est juste que nous ne pouvons pas obtenir la valeur de retour correcte, à moins que nous ne puissions pas faire défendre la déclaration «retour» qui est bizarre.
Avez-vous entendu parler de l'objet de séquence? docs.microsoft.com/en-us/sql/t-sql/statifs/... Vous devez fermement envisager de les déplacer au lieu de l'approche ici. Vous avez créé une condition de course pour obtenir de nouvelles valeurs ici. La séquence est une méthode beaucoup plus robuste de faire la même chose.
@San Lange Vous avez absolument raison. C'est juste que je m'occupe d'un dB hérité et il n'y a que tant que je peux faire à ce stade-là.
Héritage? Vous avez dit que c'est SQL Server 2014. Les séquences sont vivantes et bien en 2014.
@Sean Lange Il a été porté vers 2014 mais les personnes qui ont écrit la mise en œuvre initiale (pour des raisons) ont structuré la totalité de la DB autour de leur propre table de séquence que vous voyez ici (c'est ce que le terme «héritage» signifie dans le contexte donné) . Ce que vous voyez ici est une petite fraction d'une image beaucoup plus grande. Je ne peux pas refroidir tout le DB avec une approche plus moderne à un moment de préavis.
Vous n'avez pas besoin de refactoriser la base de données. Changer cette procédure stockée pour utiliser une séquence.