2008-10-15 9 views
7

Je lis une feuille Excel dans une grille de données. De là, j'ai réussi à lire les lignes de la grille dans un objet DataTable.L'objet DataTable contient des données parce que lorsque je fais une source de données égale à cet objet. , la grille est peuplée. Mon problème: Je veux utiliser l'objet table et manipuler ses valeurs à l'aide du serveur SQL (ie je veux le stocker comme une table temporaire et le manipuler en utilisant des requêtes SQL à partir du code C# et je veux qu'il retourne un résultat différent inte une grille. (Je ne sais pas comment travailler avec des tables temporaires en C#)Utilisation d'une table temporaire dans C#

Code est ici pour exécuter lorsque cliquant sur le bouton ....

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 

Répondre

4

Mettre les données dans une base de données prendra du temps - puisque vous l'avez déjà dans la mémoire, peut-être que LINQ-to-Objects (avec DataSetExtensions) est votre ami? Remplacer <int> etc avec les bons types ...

 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); 
     } 
+0

Cela prend du temps, mais je veux encore l'utiliser comme vitesse n'est pas encore un problème. –

0

Excusez-moi, si je ne l'ai pas compris ce que vous voulez exactement.
Si vous souhaitez effectuer une requête SQL sur une feuille Excel, vous pouvez le faire directement.

Alternativement, vous pouvez utiliser SQL Server pour interroger excel (OPENROWSET ou une fonction dont je ne me souviens pas tout de suite). En utilisant ceci, vous pouvez joindre une table de serveur de SQL avec la feuille excel

La suggestion de Marc est une autre manière de le regarder.

+0

Salut, je rapporterai plus tard si j'ai réussi. –

0

Peut-être que vous pourriez utiliser un DataView. Vous créez cela à partir d'un DataTable, que vous avez déjà. Ensuite, vous pouvez filtrer (appliquer une clause SQL WHERE) ou trier les données en utilisant les méthodes de DataView. Vous pouvez également utiliser Rechercher pour trouver une ligne correspondante ou FindRows pour rechercher toutes les lignes correspondantes.

Certains filtres:

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)" 

Tri:

dv.Sort = "City" 

Trouver une ligne: Trouver le client nommé "John Smith".

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

où i est l'indice de la ligne contenant le client. Une fois que vous les avez appliquées à DataView, vous pouvez lier votre grille à DataView.

+0

Salut, merci pour commentaires, mais comment puis-je utiliser ce type de requête ... "SELECT , , du groupe par ,

3

Je ne pense pas que vous puissiez créer une table temporaire dans SQL comme vous le pensez, car elle n'existe que dans la portée de la requête/procédure stockée qui la crée.

Si la feuille de calcul est un format standard, ce qui signifie que vous connaissez les colonnes et qu'elles sont toujours les mêmes, vous devez créer une table dans SQL pour y placer ce fichier. Il y a une façon très rapide à faire appelé 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); 

Mais, si je comprends bien votre problème correctement, vous n'avez pas besoin d'utiliser le serveur SQL pour modifier les données dans le DataTable.Vous pouvez utiliser le moteur JET pour récupérer les données pour vous.

// 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(); 

De même, dans votre code, vous demandez si votre chaîne de connexion est correcte. Je ne pense pas que ce soit (mais je peux me tromper). Si le vôtre ne fonctionne pas, essayez ceci.

connectionString="Data Source=localhost\<instance>;database=<yourDataBase>;Integrated Security=SSPI" providerName="System.Data.SqlClient" 
+0

Je préférerais utiliser votre deuxième option (en utilisant le moteur JET) .La requête J'ai besoin de faire est ce "Sélectionnez , , De groupe par , . Je pense que j'ai besoin de créer des objets colonne, mais je vais essayer de trouver –

7

Modifiez votre table temporaire de #table à ## table aux deux endroits. L'utilisation de ## signifie qu'une table temporaire globale reste en place. Vous devrez le supprimer après avoir terminé votre tâche.

Commande = "Chute Tableau ## Table"

+0

Cela va arrêter le message d'erreur, mais il y a d'autres choses à considérer avant de rendre votre table temporaire globale. Par exemple, quand il s'agit d'un seul "#", vous pouvez avoir plusieurs commandes en même temps, "##" la même table est partagée, donc vous devez être prudent dans les situations multi-thread. –

0

Modifier le texte de commande de

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

à

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