Je veux utiliser un paramètre dans la clause where uniquement si sa valeur est fournie par un ensemble de données fortement typé, c'est ce que j'essaie en ce moment, j'obtiens de bons résultats lorsque je fournis parameter3
et aucun résultat lorsque je ne donne pas sa valeur.
Ce que je désire, c'est quand je ne donne aucune valeur à parameter3
, il ne doit pas l'utiliser dans la requête, car sa valeur est nulle et je veux voir tous les résultats dans la requête, pas where Paramerter3 = null
ceux:
ALTER procedure [dbo].[GetData]
(
@Parameter1 varchar(256),
@Parameter2 varchar(256),
@Parameter3 int = null
)
AS
SELECT
*
FROM
Table1
WHERE
Table1.URL LIKE '%' + @Parameter1 + '%'
AND Table1.ID = @Parameter2
AND (@Parameter3 IS NULL OR Table1.ID2 = @Parameter3)
ORDER BY
Table1.Title
Edit: J'ai essayé la réponse de Thomas et exécuté comme ceci:
EXEC @return_value = [dbo].[GetData]
@Parameter1 = N'asda',
@Parameter2 = N'asda',
@Parameter3 = null
SELECT 'Return Value' = @return_value
GO
J'ai également mis à jour la procédure stockée comme Thomas l'a dit.
SELECT *
FROM Table1
WHERE Table1.URL LIKE '%' + @Parameter1 + '%' AND Table1.ID = @Parameter2
AND
(
@Parameter3 is null
or Table1.ID2 = @Parameter3
);
Jetez un œil à l'exemple ci-dessus. Si vous modifiez votre clause AND en une clause imbriquée OR spécifiant votre expression initiale ainsi que @Parameter3 is null
. Cela exigera alors que l'expression imbriquée soit vraie si @ Parameter3 est NULL.
J'ai toujours été fan d'une approche SQL dynamique pour ce type de problème. Je trouve qu'il fournit l'équilibre optimal entre la complexité et le plan de requête de qualité.
Dans le code suivant, je définis une requête de base qui fait tout ce qu'il faudrait faire et ensuite j'ajoute uniquement les filtres si le paramètre fourni n'est pas nul.
CREATE PROCEDURE [dbo].[GetData]
(
@Parameter1 varchar(256),
@Parameter2 varchar(256),
@Parameter3 int = null
)
AS
BEGIN
SET NOCOUNT ON;
DECLARE
@BaseQuery nvarchar(max) = N'SELECT T.* FROM dbo.Table1 AS T'
, @ParamList nvarchar(max) = N'@p1 varchar(256), @p2 varchar(256), @p3 int'
, @WhereClause nvarchar(max) = ' WHERE 1=1';
IF @Parameter1 IS NOT NULL
BEGIN
SET @WhereClause = @WhereClause + ' AND T.Url = @p1';
END
IF @Parameter2 IS NOT NULL
BEGIN
SET @WhereClause = @WhereClause + ' AND T.ID = @p2';
END
IF @Parameter3 IS NOT NULL
BEGIN
SET @WhereClause = @WhereClause + ' AND T.ID2 = @p3';
END
SET @BaseQuery = @BaseQuery + @WhereClause;
EXECUTE sp_executesql @BaseQuery, @ParamList, @p1 = @Parameter1, @p2 = @Parameter2, @p3 = @Parameter3;
END
Cela peut être beaucoup plus simple:
SELECT *
FROM Table1
WHERE Table1.URL LIKE '%' + @Parameter1 + '%' AND Table1.ID = @Parameter2
AND Table1.ID2 = ISNULL(@Parameter3, Table1.ID2)
Remarque: Je n'ai pas vu le commentaire de ConcernedOfTunbridgeWells lorsque j'ai écrit la réponse. J'ai supprimé ma réponse quand je l'ai découvert. Mais à la deuxième pensée, je pourrais simplement le garder et espérer que cela puisse aider les autres. "Où @parameter est nul ou ..." n'a pas de sens, bien que cela puisse fonctionner. L'utilisation de SQL dynamique est exagérée. J'utilise assez souvent le code suivant pour MS SQL et Sybase pour vérifier si un paramètre est nul ou vide:
SELECT *
FROM tblName
WHERE [ColumnName] = ISNULL(NULLIF(@parameter, ''), [ColumnName])
AND ('something else here')