我试图找出是否有办法在使用参数时在Sql Server中执行多值插入,确切地说,有这样的命令:
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();
是否有办法使用参数执行多值单插入,并考虑到每个值的参数可能不同? (例如:tagID可能总是不同)
我一直在互联网上搜索但到目前为止没有运气,在此先感谢,问候。
答案 0 :(得分:7)
您可以使用表值参数:How to pass table value parameters to stored procedure from .net code
首先,在SQL Server中创建类型:
CREATE TYPE [dbo].[myTvpType] AS TABLE
(
[RecordID] int,
[TagID] int
)
用于插入数据的C#代码:
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;
}
}
答案 1 :(得分:0)
您可以通过将数据作为xml字符串发送并转换为sql中存储过程中的表来完成此操作。例如: 假设我在sql表中发送多行来添加/更新,那么步骤如下:
使用以下方法将您的类或类列表转换为xml字符串:
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();
}
}
现在,在将数据发送到数据库时,将您的类对象转换为xml string(这里我在我的代码中使用实体框架,你可以在不使用它的情况下执行此操作):
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;
}
现在您的SQL代码:
3.1声明表变量:
DECLARE @tableVariableName TABLE
(
ID INT, Name VARCHAR(20)
)
3.2将xml字符串插入表变量
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最后将此表值插入到sql表中
INSERT INTO MyTable (ID, Name)
SELECT ID, Name
FROM @tableVariableName
这将节省您使用for循环一次又一次地重击数据库的努力。
希望它能帮到你