简体   繁体   中英

Insert multiple rows with parameters Sql Server

I am trying to figure out if there is a way to perform a multiple values insert in Sql Server while using parameters, to be precise, having a command like this:

com = new SqlCommand("insert into myTable values (@recID,@tagID)", con);
com.Parameters.Add("@recID", SqlDbType.Int).Value = recID;
com.Parameters.Add("@tagID", SqlDbType.Int).Value = tagID;
com.ExecuteNonQuery();

Is there a way to perform a multiple values single insert with parameters taking into account that parameters may be different for each value? (Example: tagID may be always different)

I have been searching in Internet but no luck so far, thanks in advance, greetings.

You can use a table valued parameters : How to pass table value parameters to stored procedure from .net code

First, create the type, in SQL Server :

CREATE TYPE [dbo].[myTvpType] AS TABLE 
(
    [RecordID] int,
    [TagID] int
)

And the C# code to insert your data :

internal void InsertData(SqlConnection connection, Dictionary<int, int> valuesToInsert)
{
    using (DataTable myTvpTable = CreateDataTable(valuesToInsert))
    using (SqlCommand cmd = connection.CreateCommand())
    {
        cmd.CommandText = "INSERT INTO myTable SELECT RecordID, TagID FROM @myValues";
        cmd.CommandType = CommandType.Text;

        SqlParameter parameter = cmd.Parameters.AddWithValue("@myValues", myTvpTable);
        parameter.SqlDbType = SqlDbType.Structured;

        cmd.ExecuteNonQuery();
    }
}

private DataTable CreateDataTable(Dictionary<int, int> valuesToInsert)
{
    // Initialize the DataTable
    DataTable myTvpTable = new DataTable();
    myTvpTable.Columns.Add("RecordID", typeof(int));
    myTvpTable.Columns.Add("TagID", typeof(int));

    // Populate DataTable with data
    foreach(key in valuesToInsert.Key)
    {
        DataRow row = myTvpTable.NewRow();
        row["RecordID"] = valuesToInsert[key];
        row["TagID"] = key;
    }
}

You can do this by sending your data as an xml string and convert in into table in a stored procedure in sql. For example: suppose I am sending multiple rows to add/update in an sql table then here are the steps:

  1. Convert your class or list of class into an xml string using following method:

     public static string SerializeObjectToXmlString(object value) { var emptyNamepsaces = new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }); var serializer = new XmlSerializer(value.GetType()); var settings = new XmlWriterSettings(); settings.Indent = true; settings.OmitXmlDeclaration = true; using (var stream = new StringWriter()) using (var writer = XmlWriter.Create(stream, settings)) { serializer.Serialize(writer, value, emptyNamepsaces); return stream.ToString(); } } 
  2. Now while sending data to the database convert your class object into xml string (Here I am using entity framework in my code, you can do this without using it as well):

     bool AddUpdateData(List<MyClass> data) { bool returnResult = false; string datatXml = Helper.SerializeObjectToXmlString(data); var sqlparam = new List<SqlParameter>() { new SqlParameter() { ParameterName = "dataXml", Value = datatXml} }; var result = this.myEntity.Repository<SQL_StoredProc_ComplexType>().ExecuteStoredProc("SQL_StoredProc", sqlparam); if (result != null && result.Count() > 0) { returnResult = result[0].Status == 1 ? true : false; } return returnResult; } 
  3. Now your SQL Code:

3.1 Declare a table variable:

DECLARE @tableVariableName TABLE
(
    ID INT, Name VARCHAR(20)
)

3.2 Insert Your xml string into Table variable

INSERT INTO @tableVariableName
SELECT 
    Finaldata.R.value ('(ID/text())[1]', 'INT') AS ID, 
    Finaldata.R.value ('(Name/text())[1]', 'VARCHAR(20)') AS Name
FROM @MyInputXmlString.nodes ('//ArrayMyClass/MyClass') AS Finaldata (R)

3.3 Finally insert this table value into your sql table

INSERT INTO MyTable (ID, Name)                  
SELECT ID, Name          
FROM @tableVariableName

This will save your effort of hitting database again and again using a for loop.

Hope it will help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM