Comment insérer une table de données dans la table de base de données SQL Server?

j'ai importé des données d'un fichier Excel et je les ai enregistrées dans un datatable. Maintenant j'aimerais enregistrer cette information dans mon SQL Server base de données.

j'ai vu beaucoup d'informations sur le web mais je ne comprends pas:

  1. Quelqu'un a dit insérez ligne par ligne une autre mise à jour en bloc suggérée... etc: ce qu'il de mieux?
  2. devrais-je utiliser OLE ou SQL Server objets (comme dataAdapter ou connection)?

Mon besoin est de lire l'employé rapport des heures hebdomadaires, à partir de son fichier Excel et le sauvegarder dans une table de base de données où tous les rapports sont enregistrés (mise à jour de la base de données avec de nouveaux enregistrements chaque semaine).

le fichier Excel ne contient les rapports que pour la semaine en cours.

37
demandé sur Indian 2012-01-31 10:07:07

8 réponses

Créer un User-Defined TableType dans votre base de données:

CREATE TYPE [dbo].[MyTableType] AS TABLE(
    [Id] int NOT NULL,
    [Name] [nvarchar](128) NULL
)

et définir un paramètre dans votre Stored Procedure:

CREATE PROCEDURE [dbo].[InsertTable]
    @myTableType MyTableType readonly
AS
BEGIN
    insert into [dbo].Records select * from @myTableType 
END

et envoyer votre DataTable directement au serveur sql:

using (var command = new SqlCommand("InsertTable") {CommandType = CommandType.StoredProcedure})
{
    var dt = new DataTable(); //create your own data table
    command.Parameters.Add(new SqlParameter("@myTableType", dt));
    SqlHelper.Exec(command);
}

pour éditer les valeurs à l'intérieur de la procédure stockée, vous pouvez déclarer une variable locale avec le même type et y insérer une table d'entrée:

DECLARE @modifiableTableType MyTableType 
INSERT INTO @modifiableTableType SELECT * FROM @myTableType

alors, vous pouvez éditer @modifiableTableType:

UPDATE @modifiableTableType SET [Name] = 'new value'
53
répondu Navid Farhadi 2017-12-24 05:25:58

si c'est la première fois que vous sauvegardez votre datatable

faites ceci (en utilisant la copie en vrac). Assurer il n'y a pas PK/FK contrainte

SqlBulkCopy bulkcopy = new SqlBulkCopy(myConnection);
//I assume you have created the table previously
//Someone else here already showed how  
bulkcopy.DestinationTableName = table.TableName;
try                             
{                                 
    bulkcopy.WriteToServer(table);                            
}     
    catch(Exception e)
{
    messagebox.show(e.message);
} 

maintenant que vous avez déjà un enregistrement de base. Et vous voulez juste vérifier le nouvel enregistrement avec celui existant. Vous pouvez tout simplement le faire.

en gros, prendre existantes de la table de base de données

DataTable Table = new DataTable();

SqlConnection Connection = new SqlConnection("ConnectionString");
//I assume you know better what is your connection string

SqlDataAdapter adapter = new SqlDataAdapter("Select * from " + TableName, Connection);

adapter.Fill(Table);

puis passez cette table à cette fonction

public DataTable CompareDataTables(DataTable first, DataTable second)
{
    first.TableName = "FirstTable";
    second.TableName = "SecondTable";

    DataTable table = new DataTable("Difference");

    try
    {
        using (DataSet ds = new DataSet())
        {
            ds.Tables.AddRange(new DataTable[] { first.Copy(), second.Copy() });

            DataColumn[] firstcolumns = new DataColumn[ds.Tables[0].Columns.Count];

            for (int i = 0; i < firstcolumns.Length; i++)
            {
                firstcolumns[i] = ds.Tables[0].Columns[i];
            }

            DataColumn[] secondcolumns = new DataColumn[ds.Table[1].Columns.Count];

            for (int i = 0; i < secondcolumns.Length; i++)
            {
                secondcolumns[i] = ds.Tables[1].Columns[i];
            }

            DataRelation r = new DataRelation(string.Empty, firstcolumns, secondcolumns, false);

            ds.Relations.Add(r);

            for (int i = 0; i < first.Columns.Count; i++)
            {
                table.Columns.Add(first.Columns[i].ColumnName, first.Columns[i].DataType);
            }

            table.BeginLoadData();

            foreach (DataRow parentrow in ds.Tables[0].Rows)
            {
                DataRow[] childrows = parentrow.GetChildRows(r);
                if (childrows == null || childrows.Length == 0)
                    table.LoadDataRow(parentrow.ItemArray, true);
            }

            table.EndLoadData();

        }
    }

    catch (Exception ex)
    {
        throw ex;
    }

    return table;
}

ceci retournera un nouveau DataTable avec les lignes modifiées mises à jour. Veuillez vous assurer que vous appelez la fonction correctement. La première Dattable est censée être la dernière.

puis répéter la fonction bulkcopy encore une fois avec ce nouveau datatable.

20
répondu rofans91 2013-04-26 01:00:51

je donne un code très simple, que j'ai utilisé dans ma solution (j'ai le même problème que le vôtre)

    SqlConnection con = connection string ;
//new SqlConnection("Data Source=.;uid=sa;pwd=sa123;database=Example1");
con.Open();
string sql = "Create Table abcd (";
foreach (DataColumn column in dt.Columns)
{
    sql += "[" + column.ColumnName + "] " + "nvarchar(50)" + ",";
}
sql = sql.TrimEnd(new char[] { ',' }) + ")";
SqlCommand cmd = new SqlCommand(sql, con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
cmd.ExecuteNonQuery();
using (var adapter = new SqlDataAdapter("SELECT * FROM abcd", con)) 
using(var builder = new SqlCommandBuilder(adapter))
{
adapter.InsertCommand = builder.GetInsertCommand();
adapter.Update(dt);
// adapter.Update(ds.Tables[0]); (Incase u have a data-set)
}
con.Close();

j'ai donné un tableau prédéfini le nom "abcd" (vous devez prendre soin d'un tableau par ce nom n'existe pas dans votre base de données). S'il vous plaît voter ma réponse si cela fonctionne pour vous!!!! :)

7
répondu Luv 2012-11-29 11:55:31

je vous suggère de choisir l'insertion en vrac comme suggéré dans cet article : Insertion de masse de données en utilisant C # DataTable et la fonction OPENXML de SQL server

4
répondu Pranay Rana 2012-01-31 06:10:26
public bool BulkCopy(ExcelToSqlBo objExcelToSqlBo, DataTable dt, SqlConnection conn, SqlTransaction tx)
{
    int check = 0;
    bool result = false;
    string getInsert = "";
    try
    {
        if (dt.Rows.Count > 0)
        {
            foreach (DataRow dr in dt.Rows)
            {
                if (dr != null)
                {
                    if (check == 0)
                    {
                        getInsert = "INSERT INTO [tblTemp]([firstName],[lastName],[Father],[Mother],[Category]" +
                                ",[sub_1],[sub_LG2])"+
                                " select '" + dr[0].ToString() + "','" + dr[1].ToString() + "','" + dr[2].ToString() + "','" + dr[3].ToString() + "','" + dr[4].ToString().Trim() + "','" + dr[5].ToString().Trim() + "','" + dr[6].ToString();

                        check += 1;
                    }
                    else
                    {
                        getInsert += " UNION ALL ";

                        getInsert += " select  '" + dr[0].ToString() + "','" + dr[1].ToString() + "','" + dr[2].ToString() + "','" + dr[3].ToString() + "','" + dr[4].ToString().Trim() + "','" + dr[5].ToString().Trim() + "','" + dr[6].ToString() ;

                        check++;
                    }
                }
            }
            result = common.ExecuteNonQuery(getInsert, DatabasesName, conn, tx);
        }
        else
        {
            throw new Exception("No row for insertion");
        }
        dt.Dispose();
    }
    catch (Exception ex)
    {
        dt.Dispose();
        throw new Exception("Please attach file in Proper format.");
    }
    return result;
} 
0
répondu sachin 2012-01-31 17:41:00
    //best way to deal with this is sqlbulkcopy 
    //but if you dont like it you can do it like this
    //read current sql table in an adapter
    //add rows of datatable , I have mentioned a simple way of it
    //and finally updating changes

    Dim cnn As New SqlConnection("connection string")        
    cnn.Open()
    Dim cmd As New SqlCommand("select * from  sql_server_table", cnn)
    Dim da As New SqlDataAdapter(cmd)       
    Dim ds As New DataSet()
    da.Fill(ds, "sql_server_table")
    Dim cb As New SqlCommandBuilder(da)        

    //for each datatable row
    ds.Tables("sql_server_table").Rows.Add(COl1, COl2)

    da.Update(ds, "sql_server_table")
0
répondu masoud Cheragee 2013-09-28 09:05:27

j'ai trouvé qu'il était préférable de les ajouter à la table ligne par ligne si votre table a une clé primaire. Insérer la table entière à la fois crée un conflit sur l'incrément automatique.

Voici mon Proc stocké!--4-->

CREATE PROCEDURE dbo.usp_InsertRowsIntoTable
@Year       int,
@TeamName   nvarchar(50),
AS
INSERT INTO [dbo.TeamOverview]
(Year,TeamName)
VALUES (@Year, @TeamName);
RETURN

j'ai mis ce code dans une boucle pour chaque ligne que je dois ajouter à mon tableau:

insertRowbyRowIntoTable(Convert.ToInt16(ddlChooseYear.SelectedValue), name);

Et voici ma Couche d'Accès aux Données de code:

        public void insertRowbyRowIntoTable(int ddlValue, string name)
    { 
        SqlConnection cnTemp = null;
        string spName = null;
        SqlCommand sqlCmdInsert = null;

        try
        {
            cnTemp = helper.GetConnection();
            using (SqlConnection connection = cnTemp)
            {
                if (cnTemp.State != ConnectionState.Open)
                    cnTemp.Open();
                using (sqlCmdInsert = new SqlCommand(spName, cnTemp))
                {
                    spName = "dbo.usp_InsertRowsIntoOverview";
                    sqlCmdInsert = new SqlCommand(spName, cnTemp);
                    sqlCmdInsert.CommandType = CommandType.StoredProcedure;

                    sqlCmdInsert.Parameters.AddWithValue("@Year", ddlValue);
                    sqlCmdInsert.Parameters.AddWithValue("@TeamName", name);

                    sqlCmdInsert.ExecuteNonQuery();

                }
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
        finally
        {
            if (sqlCmdInsert != null)
                sqlCmdInsert.Dispose();

            if (cnTemp.State == ConnectionState.Open)
                cnTemp.Close();
        }

    }
0
répondu jade290 2013-09-30 13:20:14

D'après ma compréhension de la question,cela peut utiliser une solution assez simple.Quoi qu'il en soit ci-dessous est la méthode que je propose ,cette méthode prend dans une table de données et puis en utilisant des instructions SQL pour insérer dans une table dans la base de données.Veuillez noter que ma solution utilise MySQLConnection et MySqlCommand et la remplacer par SqlConnection et SqlCommand.

public void InsertTableIntoDB_CreditLimitSimple(System.Data.DataTable tblFormat)
    {
        for (int i = 0; i < tblFormat.Rows.Count; i++)
        {

            String InsertQuery = string.Empty;

            InsertQuery = "INSERT INTO customercredit " +
                          "(ACCOUNT_CODE,NAME,CURRENCY,CREDIT_LIMIT) " +
                          "VALUES ('" + tblFormat.Rows[i]["AccountCode"].ToString() + "','" + tblFormat.Rows[i]["Name"].ToString() + "','" + tblFormat.Rows[i]["Currency"].ToString() + "','" + tblFormat.Rows[i]["CreditLimit"].ToString() + "')";



            using (MySqlConnection destinationConnection = new MySqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ToString()))
            using (var dbcm = new MySqlCommand(InsertQuery, destinationConnection))
            {
                destinationConnection.Open();
                dbcm.ExecuteNonQuery();
            }
        }
    }//CreditLimit
-1
répondu C.Poh 2015-12-13 03:39:11