[英]Quick insert from C# CLR
I am working on a huge set of data, and using CLR for processing it. 我正在处理大量数据,并使用CLR对其进行处理。 The CLR processing is working quick, but I need a quick way to move the processed data to the database(through CLR).
CLR处理工作很快,但是我需要一种快速的方法(通过CLR)将处理后的数据移到数据库中。
For example, see the following clr code 例如,请参见以下clr代码
protected static string Normalize(string s) // space and special character remover
{
char[] arr = s.ToCharArray();
arr = Array.FindAll<char>(arr, (c => char.IsLetterOrDigit(c)));
return new string(arr).ToLower();
}
[Microsoft.SqlServer.Server.SqlProcedure]
public static void udpNormStr ()
{
SqlConnection con = new SqlConnection("context connection = true");
SqlCommand cmd = new SqlCommand("Select cName from NamesTable", con);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
DataTable fill = new DataTable();
fill.Columns.Add("NormName", typeof(string));
da.Fill(dt);
cmd.CommandText = "insert into NormTable values (@nName)";
cmd.Parameters.Add("@nName", SqlDbType.VarChar);
foreach (DataRow row in dt.Rows)
{
fill.Rows.Add(Normalize(row[0].ToString()));
}
con.Open();
foreach (DataRow row in fill.Rows)
{
cmd.Parameters["@nName"].Value = row[0];
cmd.ExecuteNonQuery();
}
con.Close();
}
It is taking lot of time to execute, and is wasting 90% of that time in the insert operations. 执行需要花费大量时间,并且在插入操作中浪费了90%的时间。 Please suggest a better way of moving processed data to database(through CLR).
请提出一种更好的方法(通过CLR)将处理后的数据移至数据库。
SqlBulkCopy
; SqlBulkCopy
; since you have a DataTable
already, you can use: 由于您已经有一个
DataTable
,因此可以使用:
using (var bcp = new SqlBulkCopy(con))
{
bcp.DestinationTableName = "NormTable";
bcp.WriteToServer(dt);
}
Note that for streaming data, you can also create a custom IDataReader
implementation and feed that to WriteToServer
. 请注意,对于流数据,您还可以创建一个自定义
IDataReader
实现并将其提供给WriteToServer
。
Wrap your connection with a SqlTransaction to avoid implicit transactions. 用SqlTransaction包裹您的连接,以避免隐式事务。
con = new SqlConnection("context connection=true");
con.Open();
using (con)
{
using (var sqlTrans = con.BeginTransaction()) //one transaction instead of many from each insert implicit
{
const string cmdText = @"INSERT INTO [table1] ([a],[b],[c],[d],[e]) VALUES (@a,@b,@c,@d,@e)";
using (var cmd = new SqlCommand(cmdText, con, sqlTrans))
{
var aField = cmd.Parameters.Add("@a", SqlDbType.NVarChar, 255);
var bField = cmd.Parameters.Add("@b", SqlDbType.Int);
var cField = cmd.Parameters.Add("@c", SqlDbType.Bit);
var dField = cmd.Parameters.Add("@d", SqlDbType.NVarChar, 255);
var eField = cmd.Parameters.Add("@e", SqlDbType.Int);
//same for all
cField.Value = false;
dField.Value = "d";
eField.Value = 1;
foreach (var someValue in valueCollection)
{
aField.Value = someValue.Key;
bField.Value = someValue.Value;
cmd.ExecuteNonQuery();
}
}
sqlTrans.Commit();
}
con.Close();
}
Try to use SQLBulkCopy Class 尝试使用SQLBulkCopy类
this is sample method to Inset DataTable to Database in one Shot 这是一次将DataTable插入数据库的示例方法
public static bool SaveDetails(DataTable dbTable)
{
try
{
SqlConnection conn = new SqlConnection("Data Source=akshay;Initial Catalog=CosmosDB;User Id=sa;Password=Nttdata123");
conn.Open();
SqlBulkCopy sbc = new SqlBulkCopy(conn);
if (dbTable.Rows.Count > 0)
{
sbc.DestinationTableName = "Employee";
sbc.WriteToServer(dbTable);
}
sbc.Close();
conn.Close();
return true;
}
catch (Exception exp)
{
return false;
}
}
If this work is SQL/CLR, then that is tricky. 如果这项工作是SQL / CLR,那将很棘手。 One idea might be to make that method only return the data, for example as a CLR Table-Valued Function , and then do the
INSERT
back in TSQL pulling from the table-valued function. 一种想法可能是使该方法仅返回数据(例如,作为CLR表值函数) ,然后从表值函数中提取TSQL的
INSERT
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.