Я прочитал таблицу Excel в сетке данных. Оттуда мне удалось прочитать строки сетки в объекте DataTable. Объект DataTable имеет данные, потому что, когда я приравниваю источник данных сетки к этому объекту таблицы, сетка заполняется.
Моя проблема: я хочу использовать объект таблицы и управлять его значениями с помощью SQL-сервера (т.е. я хочу сохранить его как временную таблицу и управлять ею с помощью SQL-запросов из кода C#, и я хочу, чтобы он возвращал другой результат inte сетка (я не знаю, как работать с временными таблицами в C#)
Вот код для выполнения при нажатии кнопки ....
SqlConnection conn = new SqlConnection("server = localhost;integrated security = SSPI");
//is connection string incorrect?
SqlCommand cmd = new SqlCommand();
//!!The method ConvertFPSheetDataTable Returns a DataTable object//
cmd.Parameters.AddWithValue("#table",ConvertFPSheetDataTable(12,false,fpSpread2_Sheet1));
//I am trying to create temporary table
//Here , I do a query
cmd.CommandText = "Select col1,col2,SUM(col7) From #table group by col1,col2 Drop #table";
SqlDataAdapter da = new SqlDataAdapter(cmd.CommandText,conn);
DataTable dt = new DataTable();
da.Fill(dt); ***// I get an error here 'Invalid object name '#table'.'***
fpDataSet_Sheet1.DataSource = dt;
//**NOTE:** fpDataSet_Sheet1 is the grid control





Помещение данных в базу данных потребует времени - поскольку они уже есть в памяти, возможно, LINQ-to-Objects (с DataSetExtensions) - ваш друг? Замените <int> и т. д. На правильные типы ...
var query = from row in table.Rows.Cast<DataRow>()
group row by new
{
Col1 = row.Field<int>(1),
Col2 = row.Field<int>(2)
} into grp
select new
{
Col1 = grp.Key.Col1,
Col2 = grp.Key.Col2,
SumCol7 = grp.Sum(x => x.Field<int>(7))
};
foreach (var item in query)
{
Console.WriteLine("{0},{1}: {2}",
item.Col1, item.Col2, item.SumCol7);
}
Простите, если я не понял, что именно вам нужно. Если вы хотите выполнить SQL-запрос на листе Excel, вы можете сделать это напрямую.
В качестве альтернативы вы можете использовать SQL Server для запроса excel (OPENROWSET или функция, которую я сразу не помню). Используя это, вы можете присоединиться к таблице sql server с помощью excel sheet
Предложение Марка - еще один способ взглянуть на это.
Привет, я сообщу позже, если мне это удастся.
Возможно, вы могли бы использовать DataView. Вы создаете это из DataTable, который у вас уже есть.
dv = new DataView(dataTableName);
Затем вы можете отфильтровать (применить предложение SQL WHERE) или отсортировать данные с помощью методов DataView. Вы также можете использовать Find, чтобы найти соответствующую строку, или FindRows, чтобы найти все совпадающие строки.
Некоторые фильтры:
dv.RowFilter = "Country = 'USA'";
dv.RowFilter = "EmployeeID >5 AND Birthdate < #1/31/82#"
dv.RowFilter = "Description LIKE '*product*'"
dv.RowFilter = "employeeID IN (2,4,5)"
Сортировка:
dv.Sort = "City"
Поиск строки: Найдите клиента по имени «Джон Смит».
vals(0)= "John"
vals(1) = "Smith"
i = dv.Find(vals)
где i - индекс строки, содержащей покупателя.
После того, как вы применили их к DataView, вы можете привязать свою сетку к DataView.
Привет, спасибо за комментарий, но как я могу использовать этот тип запроса ... "ВЫБРАТЬ <col1>, <col2>, <sum (col3)> из группы <tablename> по <col1>, <col2>
Я не думаю, что вы можете создать временную таблицу в SQL так, как вы думаете, поскольку она существует только в рамках запроса / хранимой процедуры, которая ее создает.
Если электронная таблица является стандартным форматом, то есть вы знаете столбцы, и они всегда одинаковы, вам нужно создать таблицу в SQL, чтобы поместить в нее этот файл. Есть очень быстрый способ сделать это - SqlBulkCopy.
// Load the reports in bulk
SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString);
// Map the columns
foreach(DataColumn col in dataTable.Columns)
bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);
bulkCopy.DestinationTableName = "SQLTempTable";
bulkCopy.WriteToServer(dataTable);
Но, если я правильно понимаю вашу проблему, вам не нужно использовать SQL-сервер для изменения данных в DataTable. Вы можете использовать движок JET, чтобы получить данные за вас.
// For CSV
connStr = string.Format("Provider=Microsoft.JET.OLEDB.4.0;Data Source = {0};Extended Properties='Text;HDR=Yes;FMT=Delimited;IMEX=1'", Folder);
cmdStr = string.Format("SELECT * FROM [{0}]", FileName);
// For XLS
connStr = string.Format("Provider=Microsoft.JET.OLEDB.4.0;Data Source = {0}{1};Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'", Folder, FileName);
cmdStr = "select * from [Sheet1$]";
OleDbConnection oConn = new OleDbConnection(connStr);
OleDbCommand cmd = new OleDbCommand(cmdStr, oConn);
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
oConn.Open();
da.Fill(dataTable);
oConn.Close();
Кроме того, в вашем коде вы спрашиваете, верна ли ваша строка подключения. Не думаю (но могу ошибаться). Если ваш не работает, попробуйте это.
connectionString = "Data Source=localhost\<instance>;database=<yourDataBase>;Integrated Security=SSPI" providerName = "System.Data.SqlClient"
Я бы предпочел использовать ваш второй вариант (с использованием движка JET). Мне нужно сделать следующий запрос: «Выбрать <col1>, <col2>, <sum (col3)> From <sheetName $> group by <col1>, <col2 >. Я думаю, мне нужно создать объекты столбцов, но я попробую выяснить
Измените временную таблицу с #table на ## table в обоих местах.
Использование ## означает глобальную временную таблицу, которая остается без изменений. Вам нужно будет бросить его после того, как вы выполнили свою задачу.
Command = "Удалить таблицу ## таблица"
Это остановит сообщение об ошибке, но есть другие вещи, которые следует учитывать, прежде чем делать вашу временную таблицу глобальной. Например, когда это один «#», вы можете запускать несколько команд одновременно, «##» - одна и та же таблица, поэтому вы должны быть осторожны в многопоточных ситуациях.
Измените текст команды с
Select col1,col2,SUM(col7) From #table group by col1,col2
к
Select col1,col2,SUM(col7) From @#table group by col1,col2
Это требует времени, но я все еще хочу использовать его, так как скорость пока не является проблемой.