Код 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
Попробуйте выполнить: exec [psGetReprintNLot] 'M18111301' вместо exec [psGetReprintNLot] '721718346'. Скорее всего, у вас не получится работать должным образом.
@BishalGautam Отлично ....
вероятно, столбец codOrder в таблице Order / PackedOrder имеет тип int.





Проблема возникает из-за того, что ваш столбец 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. Так что мне нужно "М".
Если я попробую вот так:
Итак, вы имеете в виду, что правило таково: если вы передаете @codOrder с буквой M в начале, то это PackedOrder.codPackedOrder, а если на входе нет M в начале, то это PackedOrder.codOrder? Почему бы тогда не использовать IF? IF @codOrder LIKE 'M%' THEN (run one query) ELSE (run the other query) END
Возможно вы ищете это
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
@codOrder начинается с буквы М; как бы вы хотели преобразовать это в INT? Брось это? измените его на 13 (это 13-я буква алфавита), измените его на 77 (это код ascii для M)? Какие? Вы должны решить, что делать с нечисловыми символами; база данных не может решить за вас!