文章 "SQLite: MQL5 原生 SQL 数据库操纵" - 页 8 123456789101112 新评论 Daniil Kurmyshev 2021.09.06 01:33 #71 问题 2: 尝试使用ATTACH/DETACH 函数,使用SQLite 的内置机制在数据库之间传输数据,结果出现事务错误 5601... 在 SQLiteStudio 中运行同一事务时,一切正常。 这是故意为之还是有什么问题? m_db.Create("IndiTemp","indi",m_db_main.GetStruct(),true); string db_path=StringFormat("%s\\Files\\%s.sqlite", TerminalInfoString(TERMINAL_COMMONDATA_PATH), "Indi"); string query=StringFormat("ATTACH DATABASE '%s' AS X; ",db_path), tables[]; int total=m_db.GetTables(tables); if(total>0) { for(int i=0; i<total; i++) StringAdd(query,StringFormat("INSERT OR IGNORE INTO %s SELECT * FROM X.%s; ",tables[i],tables[i])); } StringAdd(query,"DETACH X; "); m_db.TransactionExecute(query); Ilyas 2021.09.06 15:21 #72 Daniil Kurmyshev 程序执行 取消),这可能是 MQL 函数内部的错误,也可能是我的程序库中的部分代码: 不幸的是,DatabaseExport 函数尚未获得导出表的功能(尽管该功能是最初打算提供的),目前仅支持查询。 关于错误 4022,你是否在测试过程中遇到过,如果是,测试仪对导出文件大小有限制--写入磁盘的数据总大小为 1GB? Ilyas 2021.09.06 18:20 #73 Daniil Kurmyshev SQLite 的内置机制在数据库之间传输数据,结果出现事务错误 5601... 在 SQLiteStudio 中执行同一事务时,一切正常。这是故意为之还是有什么问题? 查询应该有效,请检查路径是否正确 Daniil Kurmyshev 2021.09.10 03:39 #74 Ilyas #:遗憾的是,DatabaseExport 函数从未获得表格导出功能(尽管该功能是最初打算提供的),目前仅支持查询。关于错误 4022,你是否在测试过程中遇到过,如果是,测试仪对导出文件大小有限制--写入光盘的数据总大小为 1GB?如果在 DatabaseExport 函数中指定查询而不是表名,则在没有测试仪的情况下会出现错误 4022。 数据库的大小不到 10 Mb,我打算使用该功能将数据从光盘上的数据库复制到内存中的数据库。 Daniil Kurmyshev 2021.09.10 03:42 #75 Ilyas #: 查询应该有效,请检查路径是否正确 谢谢,我会尝试以不同的方式提供路径,但事实上,在 SQLiteStudio 中,指定路径下的查询是有效的,我将查询输出到终端日志,然后在 SQLiteStudio 中复制并执行,没有问题。 我会把结果写出来。 Daniil Kurmyshev 2021.09.10 03:50 #76 我知道SQLite 有这种功能,但我想知道 MT5 中是否包含这种功能,谢谢。 Aliaksandr Hryshyn 2021.09.18 12:35 #77 测试多线程写入数据库,运行多个脚本副本,每个副本都可以用 expert_id 参数标记。 #property copyright "Aliaksandr Hryshyn" #property link "https://www.mql5.com/zh/users/greshnik1" #property version "1.00" #property script_show_inputs enum e_E { e_0, e_1, e_2, e_3, }; input e_E expert_id=0; //+------------------------------------------------------------------+ //| 脚本程序启动功能| //+------------------------------------------------------------------+ void OnStart() { int db_handle=DatabaseOpen("tmp//test.sqlite",DATABASE_OPEN_READWRITE|DATABASE_OPEN_CREATE|DATABASE_OPEN_COMMON); const string sql_create= "CREATE TABLE IF NOT EXISTS Demo(" "Id INTEGER PRIMARY KEY AUTOINCREMENT," "Expert_id INTEGER," "demo_0 TEXT(2000)," "demo_1 TEXT(2000)," "demo_2 TEXT(2000)," "demo_3 TEXT(2000)," "demo_4 TEXT(2000)," "demo_5 TEXT(2000)," "demo_6 TEXT(2000)," "demo_7 TEXT(2000)" ");"; const string sql_add= "INSERT INTO Demo(Expert_id,demo_%s) VALUES(%s,'%s')"; if(!DatabaseExecute(db_handle,sql_create))//如果没有,则创建表格 { DatabaseClose(db_handle); Print("错误:",GetLastError()); Print("查询:",sql_create); return; } string s1; string sql; int err_counter=100;/记录加法错误计数器 for(int i1=0; i1<1000; i1++) { s1=""; for(int i2=0; i2<100; i2++) { s1+=string(MathRand()); } sql=StringFormat(sql_add,string(MathRand()%8),string(expert_id),s1); if(DatabaseExecute(db_handle,sql))/ 向 demo_... 数据集中的随机列中添加一条记录。 { err_counter=100; } else { if(err_counter==0) { DatabaseClose(db_handle); Print(expert_id,": end"); return; } else { Print(expert_id,": ",err_counter); err_counter--; i1--; } } if(IsStopped()) break; Sleep(1);// 睡一会儿 } DatabaseClose(db_handle); } 一切都写得很正确: 但我得到了关于阻塞的错误信息: ... 2021.09.18 13:08:05.252 Test_sql (EURUSD,M1) 2: 80 2021.09.18 13:08:05.267 Test_sql (EURUSD,M1) database error, database is locked 2021.09.18 13:08:05.267 Test_sql (EURUSD,M1) 2: 79 2021.09.18 13:08:05.283 Test_sql (EURUSD,M1) database error, database is locked 2021.09.18 13:08:05.283 Test_sql (EURUSD,M1) 2: 78 2021.09.18 13:08:05.299 Test_sql (EURUSD,M1) database error, database is locked 2021.09.18 13:08:05.299 Test_sql (EURUSD,M1) 1: 100 2021.09.18 13:08:05.315 Test_sql (EURUSD,M1) database error, database is locked 2021.09.18 13:08:05.315 Test_sql (EURUSD,M1) 1: 99 ... 应该有一种不返回错误的有条件记录插入机制。 Daniil Kurmyshev 2021.09.27 11:39 #78 Ilyas #: 查询应该有效,请确保路径正确 1.检查 ATTACH DATABASE 是否有效! 问题出在下面,我试图附加到在 RAM 中创建的数据库,在这种情况下,物理数据库的 ATTACH DATABASE 不起作用,但如果我们将 RAM 数据库附加到物理数据库,它就会 起作用! 这足以让我在 RAM 中创建一个基础副本,从而加快计算速度。) 2.我决定更进一步...并检查另一种可能性,即 ATTACH DATABASE 'file:memdb1?mode=memory&cache=shared' AS M; 根据设想,数据库应在 RAM 中创建,并在线程关闭后停止存在,但其行为却不同... 在 1 中,我可以从任何 MQL5 程序、智能交易系统、指标、脚本、服务中加入数据库、 在 2 中,其中的数据永远保存,即使重启后也是如此,我已经想过......也许数据库是物理创建的,但搜索 *memdb1*没有找到任何东西。 附注:也许是因为我从指标中创建了基础,而且它在一个共同的线程中工作? 这是个很酷的功能,但我想知道,在下一次更新和我的相关信息发布后,它是否会保留在终端中:))))。 在这种情况下,你可以轻松地在程序间传输大量数据,不会出现问题和延迟,也不会使用受名称长度限制的全局变量....。 在此执行过程中,MQL5 程序结束后,它将被删除: ATTACH DATABASE ':memory:?cache=shared' AS M; ATTACH DATABASE ':memory:' AS M; Daniil Kurmyshev 2021.11.20 17:40 #79 下午好! 请问 MT 开发人员,是否有可能禁用 SQLite 库的共享属性,因为根据其他项目 的经验,这就是 出现以下错误的原因:数据库 错误,数据库被锁定。 如果从不同线程访问数据库,则可在数据库本身层面解决,即在打开数据库后立即执行这两个查询: 1. PRAGMA journal_mode = WAL; PRAGMA busy_timeout = 1000; 但只有在使基础不共享 后,锁定错误才会消失,查询 无法 做到这一点。 Maxim Kuznetsov 2021.11.20 19:08 #80 Daniil Kurmyshev 项目 的经验,这就是 导致错误的原因:数据库错误,数据库已锁定。 如果是从不同的线程访问数据库,则可以在数据库本身的层面上解决,即在打开数据库后立即执行这两个查询:PRAGMA journal_mode = WAL;PRAGMA busy_timeout = 1000;但只有当你使基础不共享时, 锁定错误才会消失,查询 是做 不到 这一点的。 在这种情况下,查询速度会下降,内存需求也会增加....。但一切都没问题 :-)SQLite 是为一个线程或一个写入器和多个读取器设计的。许多写入者并不使用它,而使用其他不 "轻便 "的基础。 这与 MQL 无关 - 它就是这样,而且无处不在。 123456789101112 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
问题 2:
尝试使用ATTACH/DETACH 函数,使用SQLite 的内置机制在数据库之间传输数据,结果出现事务错误 5601...
在 SQLiteStudio 中运行同一事务时,一切正常。
这是故意为之还是有什么问题?
不幸的是,DatabaseExport 函数尚未获得导出表的功能(尽管该功能是最初打算提供的),目前仅支持查询。
关于错误 4022,你是否在测试过程中遇到过,如果是,测试仪对导出文件大小有限制--写入磁盘的数据总大小为 1GB?
在 SQLiteStudio 中执行同一事务时,一切正常。
这是故意为之还是有什么问题?
遗憾的是,DatabaseExport 函数从未获得表格导出功能(尽管该功能是最初打算提供的),目前仅支持查询。
关于错误 4022,你是否在测试过程中遇到过,如果是,测试仪对导出文件大小有限制--写入光盘的数据总大小为 1GB?
如果在 DatabaseExport 函数中指定查询而不是表名,则在没有测试仪的情况下会出现错误 4022。
数据库的大小不到 10 Mb,我打算使用该功能将数据从光盘上的数据库复制到内存中的数据库。查询应该有效,请检查路径是否正确
谢谢,我会尝试以不同的方式提供路径,但事实上,在 SQLiteStudio 中,指定路径下的查询是有效的,我将查询输出到终端日志,然后在 SQLiteStudio 中复制并执行,没有问题。
我会把结果写出来。
测试多线程写入数据库,运行多个脚本副本,每个副本都可以用 expert_id 参数标记。
一切都写得很正确:
但我得到了关于阻塞的错误信息:
应该有一种不返回错误的有条件记录插入机制。
查询应该有效,请确保路径正确
1.检查 ATTACH DATABASE 是否有效!
问题出在下面,我试图附加到在 RAM 中创建的数据库,在这种情况下,物理数据库的 ATTACH DATABASE 不起作用,但如果我们将 RAM 数据库附加到物理数据库,它就会 起作用!
这足以让我在 RAM 中创建一个基础副本,从而加快计算速度。)
2.我决定更进一步...并检查另一种可能性,即
ATTACH DATABASE 'file:memdb1?mode=memory&cache=shared' AS M;
根据设想,数据库应在 RAM 中创建,并在线程关闭后停止存在,但其行为却不同...
在 1 中,我可以从任何 MQL5 程序、智能交易系统、指标、脚本、服务中加入数据库、
在 2 中,其中的数据永远保存,即使重启后也是如此,我已经想过......也许数据库是物理创建的,但搜索 *memdb1*没有找到任何东西。
附注:也许是因为我从指标中创建了基础,而且它在一个共同的线程中工作?
这是个很酷的功能,但我想知道,在下一次更新和我的相关信息发布后,它是否会保留在终端中:))))。
在这种情况下,你可以轻松地在程序间传输大量数据,不会出现问题和延迟,也不会使用受名称长度限制的全局变量....。
在此执行过程中,MQL5 程序结束后,它将被删除:
ATTACH DATABASE ':memory:?cache=shared' AS M;
ATTACH DATABASE ':memory:' AS M;
下午好!
请问 MT 开发人员,是否有可能禁用 SQLite 库的共享属性,因为根据其他项目 的经验,这就是 出现以下错误的原因:数据库 错误,数据库被锁定。
如果从不同线程访问数据库,则可在数据库本身层面解决,即在打开数据库后立即执行这两个查询:
1. PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 1000;
但只有在使基础不共享 后,锁定错误才会消失,查询 无法 做到这一点。
如果是从不同的线程访问数据库,则可以在数据库本身的层面上解决,即在打开数据库后立即执行这两个查询:
PRAGMA journal_mode = WAL;
PRAGMA busy_timeout = 1000;
但只有当你使基础不共享时, 锁定错误才会消失,查询 是做 不到 这一点的。
在这种情况下,查询速度会下降,内存需求也会增加....。
但一切都没问题 :-)
SQLite 是为一个线程或一个写入器和多个读取器设计的。许多写入者并不使用它,而使用其他不 "轻便 "的基础。
这与 MQL 无关 - 它就是这样,而且无处不在。