none
C# Sql table temporaire RRS feed

  • Discussion générale

  • Bonjour, 

    Je suis en train de développer un programme.

    Je souhaite effectuer 2 requêtes que je veux stocker dans des tables temporaires et ensuite lier ces 2 tables ensemble pour en retirer un résultat (qui me servira à créer un document Excel)

    J'ai effectuer ces requêtes et cette liaison entre les 2 tables temporaires dans Sql Server Management et celles-ci fonctionnent. 

    Lorsque j'essaie de la mettre dans mon code C#, celui-ci m'indique une erreur lors de l'acces à la première table temporaire. 

    SELECT t.tn, q.name as qname
    into dbo.#table1
    FROM ticket t 
    INNER JOIN [otrs_2014].[dbo].queue q on t.queue_id = q.id 
    GROUP BY t.tn, q.name
    
    SELECT t.tn, a.a_body as bodyOpen
    into dbo.#table2
    FROM ticket t 
    INNER JOIN [otrs_2014].[dbo].article a on a.ticket_id = t.id
    GROUP BY t.tn, a.a_body
    
    
    select dbo.#table1.tn, dbo.#table1.qname, 
    from dbo.#table1, dbo.#table2
    where (dbo.#table1.tn = dbo.#table2.tn)
    order by tn
    
    drop table #table1
    drop table #table2

    Voici la requête qui fonctionne. L'erreur se situe dans le 3° select au niveau de dbo.#table1

    Avez-vous une idée de l'erreur ? 

    Merci

    • Type modifié Aurel Bera mardi 11 mars 2014 09:34 discussion
    lundi 3 mars 2014 12:31

Toutes les réponses

  • Bonjour,

    Une table temporaire n'est visible que pour une session de connexion à SQL Server.
    Dès que vous vous déconnectez la table temporaire est automatiquement détruite.

    Dans votre cas, vous créez une table temporaire pour la connexion à SQL Server Management Studio et celle-ci n'est visible que pour la connexion SQL Server Management Studio. Et donc elle n'est pas visible pour votre application C#.

    Ce que vous devez faire c'est au niveau de votre application C#, créer la table temporaire et exécuter votre requête SELECT sur cette table temporaire. Vous devez exécuter toutes ces requêtes avec la même connexion SQL (ne surtout pas faire de Close).

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance - P.O.S Informatique
    Blog : http://gilles.tourreau.fr - Suivez-moi sur Twitter
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCSA : SQL Server 2012
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 / TFS 2010 / Windows Azure

    lundi 3 mars 2014 21:09
    Modérateur
  • Bonjour, 

    Merci de votre aide. 

    Voici comment je fais en C# : 

    //La connexion est ouverte

    //Création de la table #table1

    string req = CreateRequest(); SqlDataAdapter da = new SqlDataAdapter(); SqlCommand cmd = con.CreateCommand(); cmd.CommandText = req; cmd.Parameters.AddWithValue("@date1", Convert.ToDateTime(datePicker1.Text)); cmd.Parameters.AddWithValue("@date2", Convert.ToDateTime(datePicker2.Text).AddDays(1)); cmd.Parameters.AddWithValue("@nom1", Convert.ToString(comboBoxClient1.SelectedValue)); cmd.Parameters.AddWithValue("@nom2", Convert.ToString(comboBoxClient2.SelectedValue)); da.SelectCommand = cmd; DataSet ds = new DataSet(); da.Fill(ds);

    //Création de la table #table2 string req2 = CreateRequestBodyOpen(); SqlDataAdapter da2 = new SqlDataAdapter(); SqlCommand cmd2 = con.CreateCommand(); cmd2.CommandText = req2; cmd2.Parameters.AddWithValue("@date1", Convert.ToDateTime(datePicker1.Text)); cmd2.Parameters.AddWithValue("@date2", Convert.ToDateTime(datePicker2.Text).AddDays(1)); cmd2.Parameters.AddWithValue("@nom1", Convert.ToString(comboBoxClient1.SelectedValue)); cmd2.Parameters.AddWithValue("@nom2", Convert.ToString(comboBoxClient2.SelectedValue)); da2.SelectCommand = cmd2; DataSet ds2 = new DataSet(); da2.Fill(ds2);

    //Liaison entre la #table1 et #table2 string req3 = CreateRequestFinal(); SqlDataAdapter da3 = new SqlDataAdapter(); SqlCommand cmd3 = con.CreateCommand(); cmd3.CommandText = req3; da3.SelectCommand = cmd3; DataSet ds3 = new DataSet(); da3.Fill(ds3);

    //Je ferme la connexion

    Lorsque j'exécute le code, une erreur apparaît lors de la liaison entre les tables. 

    La #table1 n'est pas reconnue. 

    Merci

    mardi 4 mars 2014 08:36
  • Bonjour,

    Le code que vous avez mis ne crée en aucun cas les tables.

    Voici un exemple de code pour créer une table depuis une application C# :

    SqlCommand cmd = con.CreateCommand();
    cmd.CommandText = "CREATE TABLE #table1 (Date1 DATETIME2, ...)";
    cmd.ExecuteNonQuery();

    Cordialement


    Gilles TOURREAU - MVP C#
    Architecte logiciel/Consultant/Formateur Freelance - P.O.S Informatique
    Blog : http://gilles.tourreau.fr - Suivez-moi sur Twitter
    - MCPD : Enterprise Developper / Windows Developper 3.5 / ASP .NET 3.5/4.0
    - MCSA : SQL Server 2012
    - MCITP : SQL Server 2008 Developper
    - MCTS : ADO .NET 3.5 / SQL Server 2008 Developper / Windows Forms 3.5 / ASP .NET 3.5/4.0 / TFS 2010 / Windows Azure

    mardi 4 mars 2014 22:38
    Modérateur
  • Voici le code que j'ai testé : 

            private void buttonTest_Click(object sender, RoutedEventArgs e)
            {
                
                Create();
                System.Windows.Forms.MessageBox.Show("Créée");
                test();
                test2();
                Drop();
                System.Windows.Forms.MessageBox.Show("Supprimée");
            }
    
            private void Create()
            {
                string req = @"CREATE TABLE #t1
                                (
                                    tn nvarchar(64),
                                    qname nvarchar(150),
                                    ttname nvarchar(150)
                                )";
                SqlCommand cmd = con.CreateCommand();
                cmd.CommandText = req;
                cmd.ExecuteNonQuery();
    
                req = @"CREATE TABLE #t2
                                (
                                    tn nvarchar(64),
                                    body nvarchar(max)
                                )";
                cmd = con.CreateCommand();
                cmd.CommandText = req;
                cmd.ExecuteNonQuery();
            }
    
            private void Drop()
            {
                string req = @"DROP table #t1";
                SqlCommand cmd = con.CreateCommand();
                cmd.CommandText = req;
                cmd.ExecuteNonQuery();
    
                req = @"DROP table #t2";
                cmd = con.CreateCommand();
                cmd.CommandText = req;
                cmd.ExecuteNonQuery();
            }
            
            private void test()
            {
                string req = CreateRequest();
                SqlDataAdapter da = new SqlDataAdapter();
                SqlCommand cmd = con.CreateCommand();
                cmd.CommandText = req;
                cmd.Parameters.AddWithValue("@date1", Convert.ToDateTime(datePicker1.Text));
                cmd.Parameters.AddWithValue("@date2", Convert.ToDateTime(datePicker2.Text).AddDays(1));
                cmd.Parameters.AddWithValue("@nom1", Convert.ToString(comboBoxClient1.SelectedValue));
                cmd.Parameters.AddWithValue("@nom2", Convert.ToString(comboBoxClient2.SelectedValue));
                da.SelectCommand = cmd;
                DataSet ds = new DataSet();
                da.Fill(ds);
    
                foreach (DataRow dr in ds.Tables[0].Rows)
                {
                    req = @"INSERT INTO #t1 (tn, qname, ttname) values ('" + Convert.ToString(dr["tn"]) + "', '" + Convert.ToString(dr["qname"]) + "', '" + Convert.ToString(dr["ttname"]) + "')";
                    cmd.CommandText = req;
                    cmd.ExecuteNonQuery();
                }
            }
    
            private void test2()
            {
                string req2 = CreateRequestBodyOpen();
                SqlDataAdapter da2 = new SqlDataAdapter();
                SqlCommand cmd2 = con.CreateCommand();
                cmd2.CommandText = req2;
                cmd2.Parameters.AddWithValue("@date1", Convert.ToDateTime(datePicker1.Text));
                cmd2.Parameters.AddWithValue("@date2", Convert.ToDateTime(datePicker2.Text).AddDays(1));
                cmd2.Parameters.AddWithValue("@nom1", Convert.ToString(comboBoxClient1.SelectedValue));
                cmd2.Parameters.AddWithValue("@nom2", Convert.ToString(comboBoxClient2.SelectedValue));
                da2.SelectCommand = cmd2;
                DataSet ds2 = new DataSet();
                da2.Fill(ds2);
    
                foreach (DataRow dr in ds2.Tables[0].Rows)
                {
                    req2 = @"INSERT INTO #t2 (tn, body) values (@tn, @bodyOpen)";
                    cmd2.CommandText = req2;
                    cmd2.Parameters.AddWithValue("@tn", Convert.ToString(dr["tn"]));
                    cmd2.Parameters.AddWithValue("@bodyOpen", Convert.ToString(dr["bodyOpen"]));
                    cmd2.ExecuteNonQuery();
                }
            }

    J'obtiens une erreur lors des insert que je fais dans la table2 :

    The variable name '@bodyOpen' has already been declared. Variable names must be unique within a query batch or stored procedure.

    Je n'utilise mon @bodyOpen a un seul endroit. 

    Avez vous une idée?

    Merci

    mercredi 5 mars 2014 15:28
  • Bonjour

    Ajoutez un cmd2.Parameters.Clear() avant ajouter les paramètres.

    Dans votre cas, une solution plus élégante sera de créer une procédure stockée avec des paramètres. Dedans vous allez créer les tables temporaires,  exécuter les select et à la fin retourner le résultat.  Les tables temporaires seront détruites automatiquement à la fin de l’exécution de la procédure.

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.


    jeudi 6 mars 2014 08:32
  • Bonjour

    Un petit retour SVP?

    Merci!

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    lundi 10 mars 2014 09:08
  • Bonjour,

    Désolé pour le retard mais tout fonctionne.

    Merci de votre aide. 

    mercredi 19 mars 2014 08:00