У меня есть список BuilderString
, который я хочу содержать данные
public List<int> IDS = new List<int>();
public List<StringBuilder> Items = new List<StringBuilder>();
Что не так с этим кодом?
SqlConnection con2 = new SqlConnection("Data Source=aya-PC\\SQLEXPRESS;Initial Catalog=ItemSet;Integrated Security=True");
SqlDataReader rdr2;
SqlCommand cmd2;
con2.Open();
for (int i = 0; i < IDS.Count; i++)
{
cmd2 = new SqlCommand("select item From TransactiontData where idT=@IDS[i]", con2);
cmd2.CommandType = CommandType.Text;
rdr2 = cmd2.ExecuteReader();
SqlParameter param = new SqlParameter();
param.ParameterName = "@IDS[i]"
while (rdr2.Read())
{
Items[i].Append((StringBuilder)rdr2["item"]);
}
}
2 ответа
Вам нужно немного изменить код:
using (SqlConnection con2 = new SqlConnection("Data Source=aya-PC\\SQLEXPRESS;Initial Catalog=ItemSet;Integrated Security=True"))
using (SqlCommand cmd2 = new SqlCommand("select item From TransactiontData where idT = @IDS", con2))
{
// add the paramter to the command
cmd2.Parameter.Add("@IDS", SqlDbType.Int);
con2.Open();
for (int i = 0; i < IDS.Count; i++)
{
// set the parameter value
cmd2.Parameter["@IDS"].Value = IDS[i];
// only *THEN* call ExecuteReader()
using (SqlDataReader rdr2 = cmd2.ExecuteReader())
{
while (rdr2.Read())
{
// **NOT SURE** what you're trying to do here.....
// First of all, you need to just call Items.Add()
// to add new items to the list - and I'm TOTALLY
// UNCLEAR what you're trying to do casting the reader
// value to a StringBuilder.......
//
// Items[i].Append((StringBuilder)rdr2["item"]);
//
// replaced with what *might* make more sense.....
Items.Add(rdr2["item"].ToString());
}
rdr.Close();
}
}
con2.Close();
}
На заметку:
Я бы рекомендовал всегда помещать ваши
SqlConnection
,SqlCommand
иSqlDataReader
в блокиusing() {...}
, чтобы обеспечить правильную утилизацию.вам нужно добавить свой параметр и установить его значение ДО вызова
.ExecuteReader()
!Поскольку сам запрос никогда не меняется, нет смысла создавать новый
SqlCommand
на каждой итерации. Создайте команду один раз, а затем просто установите параметр значение (единственное, что меняется) один раз за итерацию.
Вам нужно присвоить значение параметра в коде приложения, а не в запросе. Я не совсем уверен, чего вы пытаетесь достичь, приведя значение столбца как StringBuilder. Предполагая, что каждый элемент StringBuilder должен содержать одну строку, полученную из столбца varchar/nvarchar, приведенный ниже пример сделает это.
for (int i = 0; i < IDS.Count; i++)
{
var cmd2 = new SqlCommand("select item From TransactiontData where idT=@IDS", con2);
SqlParameter param = new SqlParameter("@IDS", SqlDbType.Int) { Value = IDS[i] };
var rdr2 = cmd2.ExecuteReader();
while (rdr2.Read())
{
Items.Add(new StringBuilder((string)rdr2["item"]));
}
}
var cmd2
над циклом, поскольку она не меняется, 2) вы должны переместить SqlParameter param = new SqlParameter("@IDS", SqlDbType.Int)
за пределы цикла, 3) установить param
внутри цикла, 4) скорее всего, не нужно while
вокруг rdr2.Read()
, и 5) вам нужно закрыть считыватель, так как вы не можете выдать другой ExecuteReader
до тех пор, пока текущий закрыт (верно?).
Похожие вопросы
Новые вопросы
sql-server
Microsoft SQL Server — это система управления реляционными базами данных (RDBMS). Используйте этот тег для всех выпусков Microsoft SQL Server, включая Compact, Express, Azure, Fast-track, APS (ранее PDW) и Azure SQL DW. Не используйте этот тег для других типов СУБД (MySQL, PostgreSQL, Oracle и т. д.). Не используйте этот тег для вопросов по программному обеспечению и разработке мобильных устройств, если только он не связан напрямую с базой данных.
cmd2.Parameter["@IDS"].Value
должна бытьIDS[i]
, 2) скорее всего, не нужно некоторое время вокругrdr2.Read()
, 3) коллекцияItems
не у вас еще нет элементов, поэтому вам нужно использоватьItems.Add()
, а не ссылаться черезItems[i]
, 4) я не думаю, что вы можете (или должны) напрямую приводить к StringBuilder, поскольку входящее значение на самом деле просто строка, и 5), вероятно, должен иметьcon2.Close()
после циклаfor
.@IDS
- нет смысла индексировать этот параметр name.... и (5) - не обязательно, так как блокиusing() {...}
обеспечивают правильное удаление (и, следовательно, закрытие) соединенияi
, но переменная C#IDS
представляет собой набор целых чисел, поэтому вам нужно использовать переменную индексаi
, чтобы получить соответствующий элемент коллекцииIDS
(иначе вам понадобится циклforeach
). Что касается № 5, я думал, что вы могли бы сказать это ;-), но я заметил, что вы закрыли SqlDataReader, поэтому я решил, что было бы разумно также закрыть соединение :). Но да, второстепенный момент.