Blog de Portekoi : Programmation et Astuces

Programmation Cobol, Php, Asp, Java et DotNet…

[SQL Server] : Retourner une valeur depuis un EXEC via sp_executesql

J’ai dernièrement été confronté à un petit dilemme : générer dynamiquement une requête SQL et en récupérer un résultat dans une variable.

Au début, j’étais parti sur cette solution :

DECLARE @SQL nvarchar(500)
DECLARE @COUNT INT

--On initialise
SET @SQL = ''
SET @COUNT = 0

--Est-ce que la table existe? Si oui, on la supprime
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
                 WHERE TABLE_SCHEMA = 'Share'
                 AND  TABLE_NAME = 'table_test')
    DROP TABLE[Share].[table_test]

-- On la crée
CREATE TABLE [Share].[table_test](
    [id] [BIGINT],
    [VALUE] VARCHAR(15)
)

--On insert deux lignes
INSERT INTO [Share].[table_test] VALUES (1, 'aaaa')
INSERT INTO [Share].[table_test] VALUES (2, 'aaaa')

-- On construit la requête
SET @SQL = 'set @count = (select count(*) from [Share].[table_test] where id = 1)'
EXEC sp_executesql @SQL

SELECT @COUNT

Mais ce code génère une erreur :

Msg 137, Niveau 15, État 1, Ligne 1
La variable scalaire « @count » doit être déclarée.

C’est tout à fait normal car dans ce cas, la variable @count n’est pas dans le même « scope » que l’exécute.

Pour contourner cela, il faudrait faire ainsi :

--(...)
-- On construit la requête
SET @SQL = 'Declare @count int '
SET @SQL = @SQL + 'set @count = 0 '
SET @SQL = @SQL + 'set @count = (select count(*) from [Share].[table_test] where id = 1)'

Mais là encore, impossible de récupérer la valeur de notre « count(*) ».

Voici la solution :

DECLARE @SQL nvarchar(500)
DECLARE @COUNT INT

--On initialise
SET @SQL = ''
SET @COUNT = 0

--Est-ce que la table existe? Si oui, on la supprime
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES
                 WHERE TABLE_SCHEMA = 'Share'
                 AND  TABLE_NAME = 'table_test')
    DROP TABLE[Share].[table_test]

-- On la crée
CREATE TABLE [Share].[table_test](
    [id] [BIGINT],
    [VALUE] VARCHAR(15)
)

--On insert deux lignes
INSERT INTO [Share].[table_test] VALUES (1, 'aaaa')
INSERT INTO [Share].[table_test] VALUES (2, 'aaaa')

-- On construit la requête
SET @SQL = @SQL + 'select @count = count(*) from [Share].[table_test] where id = 1'
EXEC sp_executesql @SQL, N'@count int out', @COUNT OUT

SELECT @COUNT --retourne '1'

J’obtiens bien ‘1’ dans ma variable @count. Si vous utilisez un ‘cursor’, n’oubliez pas de réinitialiser votre compteur.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *