web-dev-qa-db-fra.com

COLLATE DATABASE_DEFAULT contre une clause IN ()

J'ai un problème pour retourner des disques dans un sproc. Aucune erreur n'est générée, mais je pense que les données provenant d'un environnement de serveur ne se mélangent pas bien dans un autre.

set @shipedon =  YEAR(@shipdate) * 10000 + MONTH(@shipdate) * 100 + DAY(@shipdate)

Cela marche:

SELECT   [ITEM_KEY],
         max([REVISION]) Rev
FROM     SERVER2.[BOMSystem].[dbo].[ITEM]
WHERE    ITEM_KEY collate DATABASE_DEFAULT in
         ('391000180', '391000189', '391000191', '391000201',
          '391000214', '391000215', '391000216', '391000226')
AND      DATE_EFF_FROM <= @shipedon 
GROUP BY ITEM_KEY

montre 8 lignes comme:

391000180   0001
391000189   0001
391000191   0001

Cela échoue:

SELECT   [ITEM_KEY],
         max([REVISION]) Rev
INTO     #rev
FROM     SERVER2.[BOMSystem].[dbo].[ITEM] 
WHERE    ITEM_KEY collate DATABASE_DEFAULT in (@items)                                                       
AND      DATE_EFF_FROM  <= @shipedon
GROUP BY ITEM_KEY

SELECT * from #rev shows no results.

SELECT @items = SUBSTRING(
(SELECT distinct ',' +''''+ ltrim(rtrim(ItemNumber )) +'''' 
collate DATABASE_DEFAULT 
FROM #ShipTemp   
FOR XML PATH('')),2,20000) 
9
SteveO

Il n'est pas nécessaire de les concaténer dans une chaîne délimitée par des virgules.

IN accepte une sous-requête qui renvoie une seule colonne d'éléments à tester. Juste utiliser

SELECT [ITEM_KEY],
       max([REVISION]) Rev
INTO   #rev
FROM   SERVER2.[BOMSystem].[dbo].[ITEM]
WHERE  ITEM_KEY COLLATE DATABASE_DEFAULT IN (SELECT LTRIM(ItemNumber )
                                             FROM   #ShipTemp)
       AND DATE_EFF_FROM <= @shipedon
GROUP  BY ITEM_KEY 

De plus, pas besoin de RTRIM car les espaces de fin ne sont pas significatifs dans une comparaison et si ItemNumber est numérique, vous devez utiliser un type de données numérique et non une chaîne.

5
Martin Smith

Cela n'a pas de sens d'utiliser la variable @items dans la clause IN. Il traite cette variable comme une chaîne. Donc, à moins que ce ne soit qu'une valeur, cela ne fonctionnera pas comme vous le pensez.

Pour résoudre ce problème, vous devez placer tous les ID dont vous avez besoin dans une autre table temporaire, puis joindre votre requête à cette table temporaire.

SELECT ltrim(rtrim(ItemNumber )) AS ID INTO #Items FROM #ShipTemp;

SELECT   [ITEM_KEY],
         max([REVISION]) Rev
INTO     #rev
FROM     SERVER2.[BOMSystem].[dbo].[ITEM] i
         INNER JOIN #Items is ON (i.ITEM_KEY collate DATABASE_DEFAULT = is.ID)
WHERE    DATE_EFF_FROM  <= @shipedon
GROUP BY ITEM_KEY
0
user170442