Si quelqu'un peut m'aider à ce sujet, je serais très excité ... J'ai déjà passé environ 4 heures et ne peux pas savoir pourquoi T-SQL me donne des résultats erronés et la même requête en SQL est très bien (Je veux dire que seul @ZipCodeIDS n'est pas nul, c'est pourquoi j'ai mis null pour le reste des vars en plain sql).Problème de requête extrêmement laid
T-SQL Query:
-- validate the reference number pattern
DECLARE @PCodePattern nvarchar(130)
IF @PCode = '' SET @PCode = NULL
IF @PCode IS NOT NULL
BEGIN
IF LTRIM(RTRIM(@PCode)) <> ''
BEGIN
-- filter by pattern
SELECT @PCodePattern = @PCode
END
END -- @PCode
if (@strAddress is not null)
set @strAddress = '%' + @strAddress + '%'
Declare @listofIDS table(zipcodeids int)
delete from @listofIDS
IF @ZipCodeIDS = '' SET @ZipCodeIDS = NULL
IF @ZipCodeIDS IS NOT NULL
BEGIN
IF CHARINDEX(',', @ZipCodeIDS) = 0
BEGIN
insert @listofIDS values(@ZipCodeIDS)
END
ELSE
BEGIN
set @ZipCodeIDS = @ZipCodeIDS + ','
WHILE CHARINDEX(',', @ZipCodeIDS) <> 0
BEGIN
insert @listofIDS values(Left(@ZipCodeIDS, CHARINDEX(',',@ZipCodeIDS) - 1))
SET @ZipCodeIDS = SUBSTRING(@ZipCodeIDS, CHARINDEX(',',@ZipCodeIDS) + 1, LEN(@ZipCodeIDS) - CHARINDEX(',',@ZipCodeIDS))
END
END
END
-- select the property data
INSERT INTO @PropertyDetails (PropertyID, PCode, PropertyStatusID, PropertyStatusName,
PropertyTypeID, PropertyTypeName, ResearchStatusID,
ResearchStatusName, FullAddress, PartialAddress, Address1,
Address2, ZipCodeID, ZipCode, ZipCodeDescription, CityID,
CityName, StateID, StateName, StateCode, NumBedrooms, NumBathrooms,
LivingSquareFeet, LotSquareFeet, YearBuilt, ZillowLink,
AssessorParcelNumber, DateWentREO, DateAppearedOnMLS, IsOnTheMLS,
ZPropertyID, LowestPrice, HighestPrice, AskingPrice, DateTimeRecorded,
RecordedByPersonID, RecordedByPersonName, AssignedToPersonID,
AssignedToPersonName, WatchTag, Latitude, Longitude)
SELECT p.PropertyID, p.PCode, p.PropertyStatusID, ps.Name, p.PropertyTypeID, pt.Name,
p.ResearchStatusID, rs.Name, dbo.GetAddress(p.PropertyID),
dbo.GetPartialAddress(p.PropertyID), p.Address1, p.Address2, p.ZipCodeID, z.Code,
z.Description, p.CityID, c.Name, p.StateID, s.Name, s.Code, p.NumBedrooms,
p.NumBathrooms, p.LivingSquareFeet, p.LotSquareFeet, p.YearBuilt, p.ZillowLink,
p.AssessorParcelNumber, p.DateWentREO, p.DateAppearedOnMLS, p.IsOnTheMLS,
p.ZPropertyID, p.LowestPrice, p.HighestPrice, p.AskingPrice, p.DateTimeRecorded,
p.RecordedByPersonID, dbo.GetDisplayName(p.RecordedByPersonID), p.AssignedToPersonID,
dbo.GetDisplayName(p.AssignedToPersonID), w.WatchTag, p.latitude, p.longitude
FROM Properties p
JOIN cfgPropertyStatuses ps
ON ps.PropertyStatusID = p.PropertyStatusID
JOIN cfgPropertyTypes pt
ON pt.PropertyTypeID = p.PropertyTypeID
JOIN cfgResearchStatuses rs
ON rs.ResearchStatusID = p.ResearchStatusID
JOIN ZipCodes z
ON z.ZipCodeID = p.ZipCodeID
JOIN cfgStates s
ON s.StateID = p.StateID
LEFT JOIN cfgCities c
ON c.CityID = p.CityID
LEFT JOIN Watches w
ON w.PropertyID = p.PropertyID AND w.PersonID = @LoggedInPersonID
WHERE /*
******* missing filter *******
this line should filter the risks by @LoggedInPersonID via role
******************************
AND */(@PropertyID IS NULL OR p.PropertyID = @PropertyID)
AND (@PCodePattern IS NULL OR p.PCode LIKE @PCodePattern)
AND (@ZipCodeIDS IS NULL
OR p.ZipCodeID IN (select zipcodeids from @listofIDS))
AND (@NumBedroomsFrom IS NULL OR (p.NumBedrooms >= @NumBedroomsFrom
AND @NumBedroomsTo IS NOT NULL
AND p.NumBedrooms <= @NumBedroomsTo)
OR (p.NumBedrooms = @NumBedroomsFrom
AND @NumBedroomsTo IS NULL))
AND (@NumBedroomsTo IS NULL OR (p.NumBedrooms <= @NumBedroomsTo
AND (@NumBedroomsTo IS NULL OR p.NumBedrooms <= @NumBedroomsTo)))
AND (@LivingSizeFrom IS NULL OR (p.LivingSquareFeet >= @LivingSizeFrom))
AND (@LivingSizeTo IS NULL OR (p.LivingSquareFeet <= @LivingSizeTo))
AND (@LotSizeFrom IS NULL OR (p.LotSquareFeet >= @LotSizeFrom))
AND (@LotSizeTo IS NULL OR (p.LotSquareFeet <= @LotSizeTo))
AND
/* if status is null, return all. Or, return only statuses that are passed in */
(@PropertyStatuses IS NULL or
(([email protected] and (p.PropertyStatusID & (32 | 128)) = 0) or
@PropertyID is not null or @PCode is not null) or
(p.PropertyStatusID = (p.PropertyStatusID & @PropertyStatuses)))
/*
-- return the property if the specific ID was given otherwise ommit Sold and Archived
AND ((p.PropertyStatusID & (32 /*sold*/ | 128 /*archived*/)) = 0
OR @PropertyID IS NOT NULL
OR @PCode IS NOT NULL))
OR (p.PropertyStatusID = (p.PropertyStatusID & @PropertyStatuses)))
*/
AND (@PropertyTypes IS NULL
OR (p.PropertyTypeID = (p.PropertyTypeID & @PropertyTypes)))
AND (@ResearchStatuses IS NULL
OR (p.ResearchStatusID = (p.ResearchStatusID & @ResearchStatuses)))
AND (@IsOnTheMLS IS NULL OR p.IsOnTheMLS = @IsOnTheMLS)
and (@strAddress is null or (p.Address1 LIKE @strAddress or p.Address2 LIKE @strAddress))
RETURN
et même, traduit par moi dans SQL (qui fonctionne bien):
/****** Script for SelectTopNRows command from SSMS ******/
SELECT TOP 1000 [PropertyID]
,[PCode]
,[Address1]
,[Address2]
,[NumBedrooms]
,[NumBathrooms]
,[LivingSquareFeet]
,[LotSquareFeet]
,[YearBuilt]
,[ZillowLink]
,[AssessorParcelNumber]
,[DateWentREO]
,[DateAppearedOnMLS]
,[IsOnTheMLS]
,[ZPropertyID]
,[LowestPrice]
,[HighestPrice]
,[AskingPrice]
,[DateTimeRecorded]
,[RecordedByPersonID]
,[AssignedToPersonID]
,[latitude]
,[longitude]
,[Zestimate]
FROM [dev_hotsheetDB].[dbo].[Properties] p
JOIN [dev_hotsheetDB].[dbo].cfgPropertyStatuses ps
ON ps.PropertyStatusID = p.PropertyStatusID
JOIN [dev_hotsheetDB].[dbo].cfgPropertyTypes pt
ON pt.PropertyTypeID = p.PropertyTypeID
JOIN [dev_hotsheetDB].[dbo].cfgResearchStatuses rs
ON rs.ResearchStatusID = p.ResearchStatusID
JOIN [dev_hotsheetDB].[dbo].ZipCodes z
ON z.ZipCodeID = p.ZipCodeID
JOIN [dev_hotsheetDB].[dbo].cfgStates s
ON s.StateID = p.StateID
LEFT JOIN [dev_hotsheetDB].[dbo].cfgCities c
ON c.CityID = p.CityID
where
(NULL IS NULL OR p.PropertyID = NULL)
AND (NULL IS NULL OR p.PCode LIKE NULL)
AND ('1' IS NULL
OR p.ZipCodeID IN (select zipcodeids from [dev_hotsheetDB].[dbo].[listofIDS]))
AND (NULL IS NULL OR (p.NumBedrooms >= NULL
AND NULL IS NOT NULL
AND p.NumBedrooms <= NULL)
OR (p.NumBedrooms = NULL
AND NULL IS NULL))
AND (NULL IS NULL OR (p.NumBedrooms <= NULL
AND (NULL IS NULL OR p.NumBedrooms <= NULL)))
AND (NULL IS NULL OR (p.LivingSquareFeet >= NULL))
AND (NULL IS NULL OR (p.LivingSquareFeet <= NULL))
AND (NULL IS NULL OR (p.LotSquareFeet >= NULL))
AND (NULL IS NULL OR (p.LotSquareFeet <= NULL))
AND
/* if status is null, return all. Or, return only statuses that are passed in */
(NULL IS NULL or
((p.PropertyStatusID=NULL and (p.PropertyStatusID & (32 | 128)) = 0) or
NULL is not null or NULL is not null) or
(p.PropertyStatusID = (p.PropertyStatusID & NULL)))
/*
-- return the property if the specific ID was given otherwise ommit Sold and Archived
AND ((p.PropertyStatusID & (32 /*sold*/ | 128 /*archived*/)) = 0
OR @PropertyID IS NOT NULL
OR @PCode IS NOT NULL))
OR (p.PropertyStatusID = (p.PropertyStatusID & @PropertyStatuses)))
*/
AND (NULL IS NULL
OR (p.PropertyTypeID = (p.PropertyTypeID & NULL)))
AND (NULL IS NULL
OR (p.ResearchStatusID = (p.ResearchStatusID & NULL)))
AND (NULL IS NULL OR p.IsOnTheMLS = NULL)
and (NULL is null or (p.Address1 LIKE NULL or p.Address2 LIKE NULL))
S'il vous plaît noter que la question est uniquement liée à IN
déclaration. .. Quand @ZipCodeIDS = '1,2,3' il devrait retourner 414 résultats (plaine sql ok) mais la fonction T-SQL renvoie 80 ..
La chose étrange que j'ai remarquée est que T-SQL ne prend en considération que l'identifiant FIRST de @ZipCodeIDS (comme vous le voyez, je divise ces identifiants et les place dans une table temporaire). Donc, voici le problème - à propos de ce premier id ... (ne peut pas confirmer que c'est le seul problème, car il y avait des moments où pour le premier zipCodeId il ne devrait pas retourner les résultats)
Pouvez-vous donner un coup de main s'il vous plait? Ps: pour ma simple requête SQL, je l'ai utilisé une vraie table avec les ids, juste pour imiter le comportement autant que possible ...
MISE À JOUR: La division des @ZipCodeIDS et l'insertion dans la temp table fonctionne parfaitement: http://data.stackexchange.com/stackoverflow/q/109406/
déclarez une table var puis supprimez-la: pourquoi? –
Désolé, c'était un test pour s'assurer que la table est vide ... croyez-moi, c'est très moche, donc j'ai essayé de m'assurer d'autres choses, même si elles sont correctes dans la 'vraie vie' –
argument sur le laid ... Mais votre déclaration est fausse; vous n'avez pas besoin de coder pour les impossibles. –