【发布时间】:2020-09-25 14:03:35
【问题描述】:
我尝试从 C# 中填充 mySQL/MariaDB 表。读取表格并填充数据集是可行的。
表结构及其键等已给定且不能更改:
CREATE TABLE `fhem`.`history` (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32));
CREATE TABLE `fhem`.`current` (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32));
CREATE INDEX Search_Idx ON `fhem`.`history` (DEVICE, READING, TIMESTAMP);
这是我连接到数据库的代码,创建 sql 命令和适配器,然后用数据库表中的数据填充数据集。 然后我创建一个新的数据行,用值填充列并将其添加到数据集的数据表中。
class Program
{
static void Main(string[] args)
{
MySqlConnectionStringBuilder connBuilder = new MySqlConnectionStringBuilder();
connBuilder.Server = "ds2";
connBuilder.Database = "fhem";
connBuilder.UserID = "fhemdbuser";
connBuilder.Port = 3307;
connBuilder.Password = "!2345Abcde";
//connBuilder.DefaultCommandTimeout = 120;
//connBuilder.UseDefaultCommandTimeoutForEF = true;
//connBuilder.AllowUserVariables = true;
MySqlConnection conn = new MySqlConnection(connBuilder.ConnectionString);
conn.Open();
MySqlCommand selectCmdCurrent = new MySqlCommand("select `TIMESTAMP`, `DEVICE`, `TYPE`, `EVENT`, `READING`, `VALUE`, `UNIT` from current;", conn);
MySqlCommand selectCmdCurrentTest = new MySqlCommand("select `TIMESTAMP`, `DEVICE`, `TYPE`, `EVENT`, `READING`, `VALUE`, `UNIT` from currentTest;", conn);
MySqlCommand updateCmd = new MySqlCommand("update `currentTest` set `TIMESTAMP`=@p1,`DEVICE`=@p2,`TYPE`=@p3,`EVENT`=@p4,`READING`=@p5,`VALUE`=@p6,`UNIT`=@p7", conn);
updateCmd.Parameters.Add("@p1", MySql.Data.MySqlClient.MySqlDbType.DateTime);
updateCmd.Parameters.Add("@p2", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
updateCmd.Parameters.Add("@p3", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
updateCmd.Parameters.Add("@p4", MySql.Data.MySqlClient.MySqlDbType.VarString, 512);
updateCmd.Parameters.Add("@p5", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
updateCmd.Parameters.Add("@p6", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
updateCmd.Parameters.Add("@p7", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
MySqlCommand insertCmd = new MySqlCommand("insert into `currentTest` values(@p1, @p2, @p3, @p4, @p5, @p6, @p7)", conn);
insertCmd.Parameters.Add("@p1", MySql.Data.MySqlClient.MySqlDbType.DateTime);
insertCmd.Parameters.Add("@p2", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
insertCmd.Parameters.Add("@p3", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
insertCmd.Parameters.Add("@p4", MySql.Data.MySqlClient.MySqlDbType.VarString, 512);
insertCmd.Parameters.Add("@p5", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
insertCmd.Parameters.Add("@p6", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
insertCmd.Parameters.Add("@p7", MySql.Data.MySqlClient.MySqlDbType.VarString, 128);
MySqlDataAdapter dataAdapterCurrent = new MySqlDataAdapter(selectCmdCurrent);
MySqlDataAdapter dataAdapterCurrentTest = new MySqlDataAdapter(selectCmdCurrentTest);
// MySqlCommandBuilder builder = new MySqlCommandBuilder(dataAdapterCurrent);
dataAdapterCurrentTest.InsertCommand = insertCmd;
dataAdapterCurrentTest.UpdateCommand = updateCmd;
DataSet ds = new DataSet();
MySqlCommand prepareCmd = new MySqlCommand("truncate currentTest;", conn);
prepareCmd.ExecuteNonQuery();
//prepareCmd = new MySqlCommand("insert into currentTest select * from current;", conn);
//prepareCmd.ExecuteNonQuery();
prepareCmd = new MySqlCommand("INSERT INTO `currentTest` VALUES(\"2020-06-06 12:45:23\",\"DEVICE\", \"TYPE\", \"EVENT\", \"READING\", \"VALUE\", \"UNIT\")", conn);
for (int i = 0; i < 10; i++)
prepareCmd.ExecuteNonQuery();
dataAdapterCurrentTest.Fill(ds, "currentTest");
dataAdapterCurrent.Fill(ds, "current");
int row = 0;
Stopwatch sw = new Stopwatch();
for (int i = 0; i < 10; i++)
{
DataRow newrow = ds.Tables["currentTest"].NewRow();
newrow["Timestamp"] = DateTime.Now;
newrow["Device"] = "Device";
newrow["TYPE"] = "Type";
newrow["EVENT"] = "Event";
newrow["READING"] = "Reading";
newrow["VALUE"] = "Value";
newrow["UNIT"] = "Unit";
ds.Tables["currentTest"].Rows.Add(newrow);
}
dataAdapterCurrentTest.Update(ds.Tables["currentTest"]);
ds.Tables["currentTest"].AcceptChanges();
}
}
手动插入命令将正确的值放入数据库,而编程方法通过
DataRow newrow = ds.Tables["currentTest"].NewRow();
ds.Tables["currentTest"].Rows.Add(newrow);
dataAdapterCurrentTest.Update(ds.Tables["currentTest"]);
ds.Tables["currentTest"].AcceptChanges();
仅添加具有有效日期的行,但其他列为 NULL。
[编辑#1]:
我对我的代码做了一些更改,基本上我修改了第二个 for 循环以插入新数据,就像我在第一个循环中所做的那样。然后数据被正确写入数据库。但我怀疑,调用.ExecuteNonQuery() 数千次以将我的日志文件放入数据库是否是一种高效的方式......
[编辑#2]:
120 分钟后,使用.ExecuteNonQuery() 向数据库中的 100 000 次插入仍在运行。这很慢。
【问题讨论】:
-
在每种情况下,请确定您的 PRIMARY KEY
-
在“程序化方法”中,您创建了一个新的数据行,但没有给它任何值。那是实际代码还是只是精简版?顺便说一句,您不需要调用 AcceptChanges(),调用 Update() 会将所有行标记为未修改。
-
@Crowcoder:实际代码在上面的大代码部分,下面的小代码示例只是总结了动作......
-
@Strawberry:正如我在问题中所说,表格及其索引无法更改。我只有这个架构。如果我正确理解 FHEM 服务器,则行中的每一列都计入主键,因为在任何给定的时间戳,任何数量的设备都可以创建一个特定的事件,然后导致具体的读数、值和单位......跨度>
-
所以。有什么独特之处?
标签: c# mysql dataadapter