1
votes

boucle pour ajouter de la valeur dans une instruction OR dynamique

J'ai réduit cette requête à la plus élémentaire. J'ai besoin d'ajouter une instruction OR dynamiquement, qui inclut une variable. J'ai besoin d'obtenir n'importe quel identifiant et son identifiant correspondant avec un soulignement. Donc, mon @SQL résultant à exécuter serait:

SELECT OrganizationId,OrigID
    FROM #Test
    WHERE OrganizationId=@OrganizationId AND OrigID in ('31,25,33')  OR OrigID LIKE '31_%' 
    OR OrigID LIKE '33_%' 
    OR OrigID LIKE '25_%' 

Voici comment ma requête s'exécute maintenant:

SELECT OrganizationId,OrigID
    FROM #Test
    WHERE OrganizationId=@OrganizationId AND OrigID in ('31,25,33')  OR OrigID LIKE '31_%' 
SELECT OrganizationId,OrigID
    FROM #Test
    WHERE OrganizationId=@OrganizationId AND OrigID in ('31,25,33')  OR OrigID LIKE '33_%' 
SELECT OrganizationId,OrigID
    FROM #Test
    WHERE OrganizationId=@OrganizationId AND OrigID in ('31,25,33')  OR OrigID LIKE '25_%' 

C'est ce que je souhaite résultat:

create table #Test (OrganizationId varchar(100), OrigID varchar(50))
insert into #Test(OrganizationId,OrigID)
Values  ('5','31'),
        ('5','31_00000'),
        ('5','33'),
        ('5','33_00000'),
        ('5','25'),
        ('5','25_00000'),
        ('5','HD_00000'),
        ('5','HD')

-- 
DECLARE 
        @OrganizationId int = 5,
        @OriginId nvarchar(256) = N'31,25,33'




create table #inVars(id int NOT NULL IDENTITY PRIMARY KEY, origins varchar(256))
  insert into #inVars(origins)
  Values ('31'),
         ('33'),
         ('25')

 DECLARE  @SQL           NVARCHAR(MAX),
             @ParamDefinition NVARCHAR(MAX)


 SET @ParamDefinition = N'@OrganizationId int,
                        @OriginId nvarchar(256)'


SET @SQL= 'SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=@OrganizationId'

IF ISNULL(@OriginId,'') <> ''
     SET @SQL = @SQL + ' AND OrigID in (''' + @OriginId + ''') '
     DECLARE @counter INT = 1, @max INT = 0, @Origin nvarchar(50), @SQL_2 nvarchar(max)
     SELECT @max = COUNT(id) FROM #inVars
     WHILE @counter <= @max
     BEGIN
        SET @Origin = '_%'
        SET @Origin = (select origins from #invars where id = CAST(@counter as varchar(10))) + @Origin
        SET @SQL_2 = N' OR OrigID LIKE ''' + @Origin + ''' '
        SET @SQL_2 = @SQL + @SQL_2
print(@SQL_2)
        SET @counter = @counter + 1

    END

EXEC sp_executesql @SQL_2,@ParamDefinition,@OrganizationId,@OriginId

drop table #inVars
drop table #Test


12 commentaires

Salut et bienvenue à SO. Dire simplement "cela ne fonctionne pas comme prévu" n'est pas très utile. Nous ne savons pas ce que vous essayez de faire ou ce qui ne fonctionne pas. Je ne comprends pas pourquoi vous utilisez SQL dynamique ici. Pouvez-vous essayer d'expliquer ce que vous essayez de faire?


Bien sûr, désolé, c'est mon premier message ici. J'essaye d'insérer une variable dans un sql dynamique avec une clause OR. Cette requête est juste un tout petit morceau de mon uery original. J'essayais de le faire petit juste pour montrer mon besoin. J'ai besoin de sql dynamique car j'ai environ 7 autres filtres qui sont construits dynamiquement en fonction des valeurs entrées par l'utilisateur. Ce filtre d'identifiant d'origine n'est que l'un d'entre eux. Je dois pouvoir rechercher dans une table tous les identifiants que l'utilisateur entre, qui dans ce cas est 31,33,25 et leur identifiant d'origine correspondant avec un trait de soulignement à la fin (c'est-à-dire 31_, 25_, 33_).


Ajoutez ces détails à votre question. Les commentaires sont terribles pour cela car ils se perdent et le formatage est inexistant.


Pour ce type de requête catch all, vous pouvez envisager d'utiliser des paramètres de table. De plus, like utilise le trait de soulignement comme caractère générique. Voici une question sur ce sujet qui est bien expliquée. stackoverflow.com/questions/19588455/...


Je dois ajouter les identifiants d'origine avec le trait de soulignement de ma table à une instruction OR, donc j'essaie de parcourir ma table #invars et de les mettre dans une instruction OR. pour le moment, tout @Sql s'exécute plusieurs fois:


Voici comment il est exécuté maintenant: SELECT OrganizationId, OrigID FROM #Test WHERE ord.OrganizationId=@OrganizationId AND (OrigID in ('31, 25,33 ',', ') OR ord.LocNumOrig LIKE' 31_% 'SELECT OrganizationId , OrigID FROM #Test WHERE ord.OrganizationId=@OrganizationId AND (OrigID in ('31, 25,33 ',', ') OU ord.LocNumOrig LIKE' 31_% 'OU ord.LocNumOrig LIKE' 25_% 'SELECT OrganizationId, OrigID FROM #Test WHERE ord.OrganizationId=@OrganizationId AND (OrigID in ('31, 25,33 ',', ') OU ord.LocNumOrig LIKE' 31_% 'OU ord.LocNumOrig LIKE' 25_% 'OU ord.LocNumOrig COMME «33_%»


VEUILLEZ arrêter de mettre des détails dans les commentaires. Regardez à quel point cela a l'air horrible. Je ne peux pas le déchiffrer car les commentaires n'ont aucun formatage. Vous devez expliquer clairement ce que vous essayez d'accomplir, et pas simplement déclarer que cela ne fonctionne pas.


Sean Lange - Je me rends compte que je devrai peut-être ajouter un caractère d'échappement, je prends cela un petit morceau à la fois, en ce moment j'ai besoin de mon @SQl pour formater correctement. Quant aux commentaires, c'est mon premier rodéo sur SO, désolé. Je m'en souviendrai à l'avenir.


Est-ce MySQL ou SQL Server? La question comporte actuellement les deux balises.


MISE À JOUR: j'ai supprimé les commentaires.


C'est SQL Server. Je suis vraiment proche maintenant, au moins j'obtiens des résultats mais la requête s'exécute pour chaque originID au lieu d'une seule fois. Voici comment j'en ai besoin: SELECT OrganizationId, OrigID FROM #Test WHERE OrganizationId = @ OrganizationId AND OrigID in ('31, 25,33 ') OU OrigID LIKE' 31_% 'OU OrigID LIKE' 33_% 'OU OrigID LIKE' 25_ % '


ARRÊTEZ de mettre du code dans les commentaires !!!! Si vous avez besoin d'ajouter des détails à votre question, vous devez modifier votre question.


3 Réponses :


0
votes

Quelques problèmes: vous ne pouvez pas concaténer un NULL avec une chaîne EVER; le résultat est toujours NULL (veuillez regarder la ligne IF @Origin IS NOT NULL ). Dans votre boucle, vous devriez mettre à jour @SQL, pas @ SQL_2. Enfin, vous devez encapsuler les OR dans des parenthèses pour que la logique soit toujours explicite.

SET NOCOUNT ON

create table #Test (OrganizationId varchar(100), OrigID varchar(50))
insert into #Test(OrganizationId,OrigID)
Values  ('5','31'),
        ('5','31_00000'),
        ('5','33'),
        ('5','33_00000'),
        ('5','25'),
        ('5','25_00000'),
        ('5','HD_00000'),
        ('5','HD')

DECLARE 
        @OrganizationId int = 5,
        @OriginId nvarchar(256) = N'31,25,33'

create table #inVars(id int NOT NULL IDENTITY PRIMARY KEY, origins varchar(256))
  insert into #inVars(origins)
  Values ('31'),
         ('33'),
         ('25')

 DECLARE  @SQL           NVARCHAR(MAX),
             @ParamDefinition NVARCHAR(MAX)

 SET @ParamDefinition = N'@OrganizationId int,
                        @OriginId nvarchar(256)'


SET @SQL= 'SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=@OrganizationId'

IF ISNULL(@OriginId,'') <> ''
     SET @SQL = @SQL + ' AND (OrigID in (''' + @OriginId + ''') '
     DECLARE @counter INT = 1, @max INT = 0, @Origin nvarchar(50), @SQL_2 nvarchar(max)
     SELECT @max = COUNT(id) FROM #inVars
     WHILE @counter <= @max
     BEGIN
        SET @Origin = '_%'
        SET @Origin = (select origins from #invars where id = CAST(@counter as varchar(10))) + @Origin
        IF @Origin IS NOT NULL
        BEGIN
            SET @SQL_2 = N' OR OrigID LIKE ''' + @Origin + ''' '
            SET @SQL = @SQL + @SQL_2
        END
        SET @counter = @counter + 1
    END
    SET @SQL=@SQL+')'
print @SQL

drop table #inVars
drop table #Test


0 commentaires

0
votes

Ce que vous voulez ici n'est pas très clair, mais je pense que vous vous rendez la tâche plus difficile que nécessaire. Il n'est pas nécessaire d'utiliser IN, car vous recherchez également toutes les valeurs commençant par la même valeur. Et vous avez codé en dur les mêmes valeurs dans votre table temporaire. L'utilisation d'un séparateur de chaîne est environ un million de fois moins compliquée. Divisez simplement votre @OriginID entre les virgules et utilisez LIKE dans la jointure.

J'utilise DelimitedSplit8k que vous pouvez trouver ici

Je suis sûr que cela devrait vous fournir les informations que vous recherchez. Je recommanderais d'éviter les boucles autant que possible.

create table #Test (OrganizationId varchar(100), OrigID varchar(50))
insert into #Test(OrganizationId,OrigID)
Values  ('5','31'),
        ('5','31_00000'),
        ('5','33'),
        ('5','33_00000'),
        ('5','25'),
        ('5','25_00000'),
        ('5','HD_00000'),
        ('5','HD')

DECLARE 
        @OrganizationId int = 5,
        @OriginId nvarchar(256) = N'31,25,33'

select *
from #Test t
join DelimitedSplit8K(@OriginID, ',') x on t.OrigID like x.Item + '%'

drop table #Test


0 commentaires

0
votes

J'ai résolu ce problème. Merci à tous ceux qui ont répondu.

create table #Test (OrganizationId varchar (100), OrigID varchar (50)) insérer dans #Test (OrganizationId, OrigID) Valeurs ('5', '31'), ('5', '31_00000'), («5», «33»), ('5', '33_00000'), («5», «25»), ('5', '25_00000'), ('5', 'HD_00000'), ('5', 'HD')

DÉCLARER @OrganizationId int = 5, @OriginId nvarchar (256) = N'31,25,33 '

create table #inVars (id int NOT NULL IDENTITY PRIMARY KEY, origins varchar (256)) insérer dans #inVars (origines) Valeurs ('31'), («33»), ('25')

DECLARE @SQL NVARCHAR (MAX), @ParamDefinition NVARCHAR (MAX)

SET @ParamDefinition = N '@ OrganizationId int, @OriginId nvarchar (256) '

SET @SQL= 'SELECT OrganizationId,OrigID
FROM #Test
WHERE OrganizationId=@OrganizationId'

IF ISNULL(@OriginId,'') <> ''
BEGIN
     SET @SQL = @SQL +' AND (OrigID in (''' + @OriginId + ''')) '
END

IF ISNULL(@OriginId,'') <> ''

     DECLARE @counter INT = 1, @max INT = 0, @Origin nvarchar(50), @SQL_2 nvarchar(max)
     SELECT @max = COUNT(id) FROM #inVars
     WHILE @counter <= @max
     BEGIN

        SET @Origin = (select origins from #invars where id = CAST(@counter as varchar(10)))
        SET @Origin = @Origin+'_%'
        SET @SQL_2 =  N' OR (OrigID LIKE ''' + @Origin + ''') '
        SET @SQL = @SQL + @SQL_2

        SET @counter = @counter + 1

    END
    print(@SQL)

EXEC sp_executesql @SQL,@ParamDefinition,@OrganizationId,@OriginId

drop table #inVars déposer la table #Test


0 commentaires