19 08 2014
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 @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 @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.
Requêtes préparées avec Mysqli Ajouter un Timer personnalisable sur un WordPress