在c#中使用临时表

时间:2008-10-15 14:29:36

标签: c# sql temp-tables

我将excel表读入datagrid。从那里,我已经设法将网格的行读入DataTable对象.DataTable对象有数据,因为当我使网格的数据源等于该表对象时,网格被填充

我的问题:我想使用表对象并使用SQL服务器操纵它的值(即我想将它存储为临时表并使用C#代码中的SQL查询对其进行操作,我希望它返回一个不同的结果是一个网格。(我不知道如何使用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  

6 个答案:

答案 0 :(得分:7)

在两个地方将临时表从#table更改为##表。

使用##表示保留的全局临时表。完成任务后,您需要删除它。

Command =“Drop Table ## table”

答案 1 :(得分:4)

将数据放入数据库需要时间 - 因为你已经将它存储在内存中,或许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);
        }

答案 2 :(得分:3)

我认为你不能像你想象的那样在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"

答案 3 :(得分:0)

请原谅我,如果我不明白你到底想要什么 如果要在Excel工作表上执行SQL查询,可以直接执行。

或者,您可以使用SQL Server查询excel(OPENROWSET或我不记得的功能)。使用此方法,您可以使用Excel工作表加入sql server表

Marc的建议是另一种看待它的方式。

答案 4 :(得分:0)

也许您可以使用DataView。您可以从已有的DataTable创建它。

dv = new DataView(dataTableName);

然后,您可以使用DataView的方法过滤(应用SQL WHERE子句)或对数据进行排序。您还可以使用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"

寻找一行:找到名为“John Smith”的客户。

   vals(0)= "John"
   vals(1) = "Smith"
   i = dv.Find(vals)

其中i是包含客户的行的索引。

将这些应用到DataView后,您可以将网格绑定到DataView。

答案 5 :(得分:0)

更改命令文本
Select col1,col2,SUM(col7) From #table group by col1,col2

Select col1,col2,SUM(col7) From @#table group by col1,col2