Member 13852666 Ответов: 2

Sql хранимая процедура передача массива


У меня есть datagridview, где мне нужно отобразить отфильтрованный поиск каналов:

пользователь будет указывать:
@ChannelType int,
@ChannelStatus	int,
@govId int,
@DistId int,
@Budget money,
@dt varchar(max),
@minSqm int,
@maxSqm int


Моя проблема заключается в списке спецификаций (@dt): это checkedlistbox, где пользователь будет выбирать спецификации, и я должен найти каналы, у которых есть выбранные спецификации.
Поэтому мне нужно сохранить это в массиве, чтобы сделать where в близком состоянии.


Поэтому я перечислил идентификатор элемента спецификации в массиве в c# и попытался передать его в sql, но он не работает.

Что я уже пробовал:

Хранимая процедура:
USE [Tenant Management]
GO
/****** Object:  StoredProcedure [dbo].[BuySearchEngine]    Script Date: 8/31/2018 4:22:27 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[BuySearchEngine]
@ChannelType int,
@ChannelStatus	int,
@govId int,
@DistId int,
@Budget money,
@dt varchar(max),
@minSqm int,
@maxSqm int

AS
select DISTINCT  c.ID,c.Name,cc.[Channel Category], gv.GOVERNATOR + ' '+dst.District+' '+ct.City +' '+c.street As Location,c.Surface
,c.Floor,c.[Selling Price],c.[Market price] 
from [dbo].[Channel_availableSpecs] asp
inner join [dbo].[Channel] c on asp.Channel_Id = c.ID 
inner join [dbo].[Channel_Category] cc on c.[Channel Category ID] = cc.ID
inner join [dbo].[Governator] gv on c.[Governator ID] = gv.ID
inner join [dbo].[District] dst on c.[District ID] = dst.id
inner join [dbo].[City] ct on c.[City ID] = ct.id
where  c.[Channel Type] =@ChannelType
   and c.[Channel Status]=@ChannelStatus
   and c.[Governator ID]=@govId
   and c.[District ID]=@DistId
   and c.[Selling Price] < @Budget
   and c.Surface >= @minSqm
   and c.Surface <= @maxSqm
   and asp.ChennelSpec_Id IN (SELECT asp.ChennelSpec_Id FROM  Fn_split(@dt, ','))


С#:

       List<string> list = new List<string>();
 private void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
       {
           list.Add(checkedListBox1.SelectedValue.ToString());


       }

private void next_Click(object sender, EventArgs e)
       {   int govId,distId,minSqm,maxSqm;
           Int32.TryParse(governator.SelectedValue?.ToString(),out govId);
           Int32.TryParse(district.SelectedValue?.ToString(),out distId);
           Int32.TryParse(sqm_from.Text,out minSqm);
           Int32.TryParse(sqm_to.Text,out maxSqm);

           if (rentbutton == 1)
           {
               rent_panel.Show();

           }
           else
           {
               buy_search_panel.Show();
               string[] Specs = new string[list.Count];
               Utilities.BuySearch(Specs, govId, distId, minSqm,maxSqm,availability);
               list.Clear();
           }
           availabilityFill();
       }






 public static void BuySearch(Array array,int govId,int distId, int minSqm,int maxSqm,DataGridView dataGridView)
       {
             string specs = Get_comma_delimited_string(array);
             SqlConnection conn = new SqlConnection(ConnectionString);
             SqlCommand cmd = conn.CreateCommand();

           cmd.CommandText = "Execute BuySearchEngine @ChannelType, @ChannelStatus, @govId, @DistId, @Budget, @dt";
           cmd.Parameters.Add("@ChannelType", SqlDbType.Int).Value = "1";
           cmd.Parameters.Add("@ChannelStatus", SqlDbType.Int).Value ="5" ;
           cmd.Parameters.Add("@govId", SqlDbType.Int).Value = govId;
           cmd.Parameters.Add("@DistId", SqlDbType.Int).Value = distId;
           cmd.Parameters.Add("@dt", SqlDbType.VarChar).Value = specs;
           cmd.Parameters.Add("@minSqm", SqlDbType.Int).Value = minSqm;
           cmd.Parameters.Add("@maxSqm", SqlDbType.Int).Value = maxSqm;
           conn.Open();
           DataTable dt = new DataTable();
           cmd.CommandType = CommandType.StoredProcedure;
           SqlDataAdapter da = new SqlDataAdapter(cmd);
           da.Fill(dt);
           dataGridView.DataSource = dt;
           conn.Close();

       }

2 Ответов

Рейтинг:
2

Tim Schwallie

Что возвращает Fn_split?
Я не верю, что он возвращает аспида.ChennelSpec_Id для каждого элемента в @dt.
если он возвращает столбец, то, возможно, потребуется сделать небольшое изменение в выборе:

Выберите whateverthenameofthereturncolumnis из Fn_split(@dt, ',')


Member 13852666

Я пытался отправить спецификации в массив, но это не работает. поэтому я отправляю список в строке, разделенной запятыми, так что Fn_split возвращает все элементы.

Рейтинг:
15

Richard Deeming

and asp.ChennelSpec_Id IN (SELECT asp.ChennelSpec_Id FROM Fn_split(@dt, ','))

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

Ваш код эквивалентен:
and asp.ChennelSpec_Id = asp.ChennelSpec_Id
что, очевидно, будет верно для каждой строки, где asp.ChennelSpec_Id не является NULL.

Вам нужно сравнить их со значениями, возвращенными из вашего компьютера. Fn_split функция. Точный код будет зависеть от имени столбца, возвращаемого этой функцией, но он будет выглядеть примерно так:
and asp.ChennelSpec_Id IN (SELECT value FROM Fn_split(@dt, ','))


Member 13852666

Я пытался изменить его и многие другие, но все еще не работает.

Я получаю сообщение об ошибке: 'не удалось найти хранимую процедуру 'выполнение BuySearchEngine @ChannelType, @ChannelStatus, @govId, @DistId, бюджетные@, @ц'.'

Richard Deeming

Если вы используете ADO.NET и установка CommandText к "Execute BuySearchEngine @ChannelType, @ChannelStatus, @govId, @DistId, @Budget, @dt", то вам нужно установить CommandType к Text.

Кроме того, установите CommandType к StoredProcedure, и установить CommandText к "BuySearchEngine", без имен параметров или Execute.

Если он все еще не работает, то хранимая процедура не существует в базе данных, к которой вы подключаетесь.

Member 13852666

string specs = Get_comma_delimited_string(массив);
Ящик для сообщений.Показать(технические характеристики);
Объект sqlconnection соед = новый объект sqlconnection(connectionString и);
SqlCommand cmd = conn.CreateCommand();

УМК.CommandType = CommandType.Хранимая процедура;
УМК.CommandText = "BuySearchEngine @ChannelType, @ChannelStatus, @govId, @DistId, @Budget, @dt,@minSqm,@maxSqm";
cmd.Parameters.Add("@ChannelType", SqlDbType.Int).Значение = "1";
cmd.Parameters.Add("@ChannelStatus", SqlDbType.Int).Значение = "5";
cmd.Parameters.Add("@govId", SqlDbType.Int).Значение = говид;
cmd.Parameters.Add("@DistId", SqlDbType.Int).Значение = distId;
УМК.Параметры.Добавить("@ДТ", значения sqldbtype.Тип varchar).Значение = технические характеристики;
cmd.Parameters.Add("@minSqm", SqlDbType.Int).Значение = минквм;
cmd.Parameters.Add("@maxSqm", SqlDbType.Int).Значение = maxSqm;
Коннектикут.Открыть();
DataTable dt = новый DataTable();
УМК.CommandType = CommandType.Хранимая процедура;
SqlDataAdapter da = новый SqlDataAdapter(cmd);
да.Заполнить(ДТ);
практическое руководство.Источник данных = ДТ;
Коннектикут.Закрывать();


Все еще не работает, не удалось найти хранимую процедуру BuySearchEngine

Richard Deeming

cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "BuySearchEngine @ChannelType, @ChannelStatus, @govId, @DistId, @Budget, @dt,@minSqm,@maxSqm";


Вернитесь и прочитайте мой предыдущий комментарий еще раз.

"Установите CommandType к StoredProcedure, и установить CommandText к "BuySearchEngine", без имен параметров или Execute."

cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "BuySearchEngine"; // WITHOUT the parameter names!

Member 13852666

Спасибо