Как передать массив строк, подобный хранимой процедуре?

#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.
  

Я хотел передать это как хранимую процедуру, но заблудился, с чего начать сейчас.

Вещи, которые я пробовал:

  1. Попробуйте использовать функцию 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» здесь не применяется