Чрезвычайно уродливый вопрос - PullRequest
0 голосов
/ 13 августа 2011

Если кто-нибудь может помочь мне в этом, я был бы очень взволнован ... Я уже потратил около 4 часов и не могу понять, почему T-SQL дает мне неправильные результаты, и тот же запрос в SQL хорошо (я имею в виду только @ZipCodeIDS не равен null, поэтому я оставил значение null для остальных переменных в обычном sql).

Запрос T-SQL:

-- 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 
                ((p.PropertyStatusID=@PropertyStatuses 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

и то же самое, переведенное мной в SQL (что хорошо работает):

    /****** 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))

Обратите внимание, что проблема связана только с оператором IN ... Когда @ZipCodeIDS = '1,2,3', она должна возвращать 414 результатов (обычный sql ok), но функция T-SQL возвращает 80 ..

Странная вещь, которую я заметил, заключается в том, что T-SQL учитывает только ПЕРВЫЙ идентификатор из @ ZipCodeIDS (как вы видите, я разделил эти идентификаторы и поместил их во временную таблицу). Итак, вот проблема - об этом первом идентификаторе ... (не могу подтвердить, что это единственная проблема, потому что были времена, когда для первого zipCodeId он не должен ничего возвращать, но все равно возвращал результаты)

Не могли бы вы помочь, пожалуйста? PS: для моего простого sql-запроса я использовал реальную таблицу с этими идентификаторами, просто чтобы максимально имитировать поведение ...

ОБНОВЛЕНИЕ : разбиение @ZipCodeIDS и вставка в временную таблицу работает отлично: http://data.stackexchange.com/stackoverflow/q/109406/

1 Ответ

2 голосов
/ 13 августа 2011

Решил проблему с помощью Timbo !!!!!

Я объявил @ZipCodeIDS varchar и каким-то образом это сделано по умолчанию VARCHAR (1).

Я изменил его на @ZipCodeIDS varchar (50), и он не прекрасно работает !!!!

Извините, ребята, потому что это заявление было скрыто от вас!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...