SQL Странная Ошибка преобразования типа данных nvarchar в числовую Ошибка.Ошибка только в предложении Where - PullRequest
2 голосов
/ 08 июля 2019

Итак, у меня есть этот запрос

select * 
FROM    
    [JMNYC-AMTDB].[AMTPLUS].[dbo].PickTickets i                         WITH (NOLOCK)           

    INNER JOIN 
    [JMNYC-AMTDB].[AMTPLUS].[dbo].customer_store cs                     WITH (NOLOCK) 
                                                                        ON i.Company_code = cs.Company_code
                                                                        AND i.Division_code = cs.Division_code
                                                                        AND i.Customer_Number = cs.Customer_Number
                                                                        AND i.ShipTo=cs.store_number
    JOIN 
    [JMNYC-AMTDB].[AMTPLUS].[dbo].PickTickets_Packing ps1               WITH (NOLOCK) 
                                                                        ON i.Company_Code=ps1.Company_Code 
                                                                        AND i.Division_Code=ps1.Division_Code 
                                                                        AND i.PickTicket_Number=ps1.PickTicket_Number
    JOIN 
    [JMNYC-AMTDB].[AMTPLUS].[dbo].Orders o                              WITH (NOLOCK) 
                                                                        ON i.Company_Code=o.Company_Code 
                                                                        AND i.Division_Code=o.Division_Code 
                                                                        AND i.Control_Number=o.Control_Number
    LEFT JOIN 
    [JMNYC-AMTDB].[AMTPLUS].[dbo].Country cr                            WITH (NOLOCK)
                                                                        ON cs.country  =cr.country 

    LEFT JOIN 
    Packslip P                                                          ON I.COMPANY_CODE=P.CLIENTNAME

    LEFT JOIN 
    Moret_shipper sh                                                    ON I.COMPANY_CODE=sh.CLIENTNAME

    LEFT JOIN 
    CUSTOMER cu                                                         ON i.Customer_Number=cu.CUST_NUM

    LEFT JOIN 
    (       
        SELECT packslip FROM PICKHEAD (NOLOCK) 
        WHERE CLIENTNAME='03'
    ) td3                                                               ON I.PickTicket_number=td3.packslip

    JOIN 
    [JMNYC-AMTDB].[AMTPLUS].[dbo].Picktickets_stage pst1                WITH (NOLOCK) 
                                                                        ON i.Company_Code=pst1.Company_Code 
                                                                        AND i.Division_Code=pst1.Division_Code 
                                                                        AND i.PickTicket_Number=pst1.PickTicket_Number 
                                                                        AND pst1.Stage_code='940READY'
    LEFT JOIN 
    (
        SELECT packslip FROM rf_log_all (NOLOCK) 
        WHERE action='DELETESO' AND clientname='03'
    ) td4                                                               ON I.PickTicket_number=cast(td4.packslip as numeric)

Если я запускаю его просто так, кажется, все работает нормально.

Однако, как только я начинаю добавлять предложение where, я получаю странную ошибку преобразования.

Вот мое предложение where:

WHERE  
    i.company_code='03' 
    AND ps1.Packed_Status='E' 
    AND i.Warehouse_Code in ('DAYTO','SANFE','ALLLM')
    AND td3.packslip is null 
    AND td4.packslip is null

При этом я получаю сообщение об ошибке при преобразовании типа данных nvarchar в числовой.

Если я закомментирую проверки td3 и td4, это сработает.

WHERE  
    i.company_code='03' 
    AND ps1.Packed_Status='E' 
    AND i.Warehouse_Code in ('DAYTO','SANFE','ALLLM')
    --AND td3.packslip is null 
    --AND td4.packslip is null

Однако он также работает с оставшимися, но закомментирована балансовая единица.

WHERE  
    --i.company_code='03' AND
     ps1.Packed_Status='E' 
    AND i.Warehouse_Code in ('DAYTO','SANFE','ALLLM')
    AND td3.packslip is null 
    AND td4.packslip is null

Кто-нибудь знает, что может быть причиной этой ошибки. Это запрос, который мы использовали некоторое время, и эта проблема началась недавно. Если бы я знал, какая именно строка вызывает эту ошибку, я мог бы попытаться исправить ее, но я даже не уверен в этом.

1 Ответ

1 голос
/ 08 июля 2019

Это слишком долго для комментария.

Очевидно, что ничего в предложении where не вызывает эту ошибку, потому что все сравнения являются сравнениями строк (или безопасны по типу, такие как сравнение с NULL).

Итак, некоторые условия JOIN вызывают проблемы. Это означает, что вы смешиваете типы. У вашего вопроса недостаточно информации, чтобы определить, какие из них.

Почему это происходит с некоторыми WHERE условиями, а не с другими? Потому что SQL Server реорганизует план запроса, чтобы он был оптимальным для написанного вами запроса. В разных планах запросов оскорбительное сравнение может выполняться после фильтрации (в этом случае ошибки не возникает) или перед фильтрацией (в случае ошибки).

Чтение плана запроса, вероятно, не поможет вам. Вы действительно хотите найти сравнение, которое смешивает типы - и это может занять немного работы и копаться в структурах таблиц.

Если бы мне пришлось угадывать, я бы предположил, что оскорбительная строка кода:

ON I.PickTicket_number = cast(td4.packslip as numeric)

И это packslip не всегда может быть преобразовано в числовое значение. Это легко исправить с помощью try_cast():

ON I.PickTicket_number = try_cast(td4.packslip as numeric)
...