#c# #sql-server
#c# #sql-сервер
Вопрос:
Я использую asp mvc c #, и я хочу знать, возможно ли передать мой массив, подобный строке, в управляемый в хранимой процедуре. У меня есть пример ниже:
C#
string temp="123,234,234";
SQL:
@temp varchar(50)
Select * from table where column in @temp
Он возвращает
Conversion failed when converting the nvarchar value '123,234,234' to data type int.
Я хотел передать это как хранимую процедуру, но заблудился, с чего начать сейчас.
Вещи, которые я пробовал:
- Попробуйте использовать функцию Replace, но по-прежнему не работает.
Комментарии:
1. Как говорится в сообщении об ошибке, вам нужно будет сделать ваш temp целым числом вместо varchar .
2. Пожалуйста, убедитесь, что используемые вами теги относятся к вашему конкретному вопросу.
[vb.net]
и[asp.net-mvc]
здесь не имеют никакого отношения.3. @earvin пометка на нескольких языках, было бы более приемлемо, если бы вы сказали «Я приму ответ в vb.net тоже, потому что я это знаю» — как правило, если вы использовали только один язык в вопросе, вы должны поставить только один тег
4. извините, я просто использовал его снова, извините за неправильные теги
Ответ №1:
Как вы обнаружили, вы не можете этого сделать, потому что строка, содержащая числовые последовательности символов, разделенные запятыми, — это не то же самое, что программа SQL, которая содержит постоянные числа, разделенные запятыми. Например, вы бы не ожидали, что этот c # тоже будет работать:
int[] a = new [] { 1,2,3 }; //works
int[] b = "new [] { 1,2,3 }"; //doesn't work
И вы бы не ожидали, что это сработает (что на самом деле вы и делаете:
SELECT * FROM t WHERE x IN('1,2,3')
Если бы ваш столбец был строкой, вы бы не получили ошибку, но она также не работала бы так, как вы ожидаете
SELECT * FROM t WHERE x IN ('a','b'). --works
SELECT * FROM t WHERE x IN ('''a'',''b'''). --valid, but doesn't select x that are "a" or "b"
Итак, all in, IN — это как функция, которая принимает N аргументов различных типов. Он не просматривает строку, которую вы передаете, и не видит, что в ней есть запятые, и не разделяет их
Таким образом, вы либо передаете столько параметров, сколько у вас есть элементов:
SELECT * FROM t WHERE x IN (@p1, @p2, @p3)
Ваш sproc принимает 3 параметра, вы вводите одно значение для каждого параметра, если вы ищете только два числа, вы просто повторяете последнее число, потому IN(1,2,2)
что оно совпадает с IN(1,2)
Или вы создаете тип:
CREATE TYPE dbo.IntList AS TABLE
(
X INT NOT NULL
)
Вы объявляете свой sproc для получения переменной этого типа
@numList x
Вы объявляете datatable в c #, который представляет этот тип
var dt = new DataTable();
dt.Columns.Add("X", typeof(int));
Вы заполняете его одним int на строку
Вы объявляете свой параметр как структурированный
command.Parameters.AddWithValue("@numList", dt).SqlDbType = SqlDbType.Structured;
И вы выполняете его. Помните, что ваш @numList — это таблица, подобная любой другой, поэтому вы не можете сказать SELECT * FROM t WHERE x IN (@numlist)
, вы либо делаете SELECT * FROM t JOIN @numList n ON t.x = n.x
, либо SELECT * FROM t WHERE x IN (SELECT x FROM @numlist)
и т. Д
Комментарии:
1. Пожалуйста, обратите внимание, что «можем ли мы прекратить использовать AddWithValue» здесь не применяется