Как преобразовать результат в строку из int SQL Server

Код SQL:

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;

    SELECT DISTINCT 
        codPackedBatch AS codPackedBatch
    FROM            
        PackedOrder 
    INNER JOIN
        [Order] ON PackedOrder.codOrder = [Order].codOrder
    WHERE
        (PackedOrder.codOrder = @codOrder OR @codOrder IS NULL)
        AND RIGHT([PackedOrder].codPackedBatch, 1) <> 8 
    ORDER BY
        codPackedBatch ASC

    IF @@Error <> 0 
        RETURN -1
    ELSE
        RETURN 0

    SET NOCOUNT OFF
END

Проблема:

У меня есть @codOrder со строкой = 'M18111301'.

Exec [psGetReprintNLot] 'M18111301'

Когда я пытаюсь выполнить хранимую процедуру, я получаю такую ​​ошибку:

Msg 245, Level 16, State 1, Procedure psGetReprintNLot, Line 47
Conversion failed when converting the varchar value 'M18111301' to data type int.

Но когда я пытаюсь выполнить:

Exec [psGetReprintNLot] '721718346' 

он работает, как ожидалось. Как мне получить значения, если я ввожу строку?

Если я попробую, как показано ниже: я получаю правильный результат для «M», но не для обычного «72 ... 46»

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;
    --SELECT DISTINCT codPackedBatch as codPackedBatch
    --FROM PackedOrder 
    --INNER JOIN [Order] ON PackedOrder.codOrder = [Order].codOrder
    --WHERE (PackedOrder.codOrder = @codOrder or @codOrder IS NULL)
    --AND Right([PackedOrder].codPackedBatch,1) <> 8 order by codPackedBatch Asc                    
    SELECT DISTINCT codPackedBatch AS codPackedBatch
    FROM PackedOrder 
    WHERE (PackedOrder.codPackedOrder = @codOrder OR @codOrder IS NULL) 
      AND RIGHT([PackedOrder].codPackedBatch, 1) <> 8 
    ORDER BY codPackedBatch ASC

    IF @@Error <> 0 
        RETURN -1
    ELSE
        RETURN 0

    SET NOCOUNT OFF
END

@codOrder начинается с буквы М; как бы вы хотели преобразовать это в INT? Брось это? измените его на 13 (это 13-я буква алфавита), измените его на 77 (это код ascii для M)? Какие? Вы должны решить, что делать с нечисловыми символами; база данных не может решить за вас!

Caius Jard 26.11.2018 10:55

Попробуйте выполнить: exec [psGetReprintNLot] 'M18111301' вместо exec [psGetReprintNLot] '721718346'. Скорее всего, у вас не получится работать должным образом.

BishalG 26.11.2018 10:57

@BishalGautam Отлично ....

Ravi 26.11.2018 10:58

вероятно, столбец codOrder в таблице Order / PackedOrder имеет тип int.

Ravi 26.11.2018 11:20
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
173
2

Ответы 2

Проблема возникает из-за того, что ваш столбец PackedOrder.codOrder имеет тип данных INT, и вы сравниваете его с varchar:

PackedOrder.codOrder = @codOrder

Когда строка @codOrder содержит только числа, SQLServer успешно преобразует содержимое @codOrder в INT, а затем выполнит запрос.

Когда ваш @codOrder также содержит альфа-символы, SQLServer не сможет преобразовать его в int и выдаст эту ошибку

SQLServer не будет пытаться преобразовать все данные вашей таблицы в varchar, чтобы выполнить сравнение типа строка: строка, потому что преобразование данных таблицы неявно для соответствия такой переменной, как эта, расходует ресурсы, и в большинстве случаев преобразования данных означают, что нельзя использовать индексы. Все это означает, что преобразование миллионов строк в соответствии с типом данных одной переменной имеет ужасные последствия для производительности и не должно выполняться.

Если вы действительно хотите сделать это преобразование явно, вы можете выполнить CAST () свой столбец таблицы в varchar, но смотритеinf, поскольку столбец таблицы является INT, он никогда не будет содержать M18111301, поэтому преобразование миллиона INT в varchar, а затем поиск в них алфавитно-цифровые символы - это на 100% бессмысленное занятие.

Вам было бы лучше изменить свою процедуру, чтобы вместо этого использовался INT, набранный @codOrder, и прекратить попытки вводить в него буквенно-цифровые данные

В качестве альтернативы, согласно комментарию под вопросом, если M18111301 каким-либо образом связан с данными в таблице (например, таблица действительно содержит 18111301, поэтому вы должны отключить M), затем измените переменную, чтобы она соответствовала чему-то в стол и выполните поиск


В ответ на ваше изменение и мой комментарий ниже:

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;

  IF @codOrder LIKE 'M%'
    SELECT DISTINCT codPackedBatch AS codPackedBatch
    FROM PackedOrder 
    WHERE (PackedOrder.codPackedOrder = @codOrder OR @codOrder IS NULL) 
      AND RIGHT([PackedOrder].codPackedBatch, 1) <> 8 
    ORDER BY codPackedBatch ASC
  ELSE
    SELECT DISTINCT codPackedBatch as codPackedBatch
    FROM PackedOrder 
    INNER JOIN [Order] ON PackedOrder.codOrder = [Order].codOrder
    WHERE (PackedOrder.codOrder = @codOrder or @codOrder IS NULL)
    AND Right([PackedOrder].codPackedBatch,1) <> 8 order by codPackedBatch Asc     
  END IF;

    IF @@Error <> 0 
        RETURN -1;
    ELSE
        RETURN 0;

    SET NOCOUNT OFF;
END

?

Если вы ожидаете значений @codOrder, которые имеют какие-либо альфа-символы где-либо еще, например 123TP456, вы можете протестировать с LIKE '%[A-Z]%'

Да, ваше понимание правильное. Но мне нужен какой-то результат, который присутствует как в codOrder, так и в Codpackedorder. Так что мне нужно "М".

Naman 26.11.2018 11:10

Если я попробую вот так:

Naman 26.11.2018 11:12

Итак, вы имеете в виду, что правило таково: если вы передаете @codOrder с буквой M в начале, то это PackedOrder.codPackedOrder, а если на входе нет M в начале, то это PackedOrder.codOrder? Почему бы тогда не использовать IF? IF @codOrder LIKE 'M%' THEN (run one query) ELSE (run the other query) END

Caius Jard 26.11.2018 11:21

Возможно вы ищете это

ALTER PROCEDURE [dbo].[psGetReprintNLot]
    @codOrder VARCHAR(15)   
AS
BEGIN
    SET NOCOUNT ON;

    SELECT DISTINCT codPackedBatch as codPackedBatch
    FROM PackedOrder 
    INNER JOIN [Order] ON PackedOrder.codOrder = [Order].codOrder
    WHERE (@codOrder IS NULL or @codOrder = case when isnumeric(@codOrder) then PackedOrder.codOrder else PackedOrder.codPackedOrder end)
    AND Right([PackedOrder].codPackedBatch,1) <> 8 order by codPackedBatch Asc      

   IF @@Error <> 0 
        RETURN -1
    ELSE
        RETURN 0

    SET NOCOUNT OFF
END

Другие вопросы по теме