DatabaseExport
将表格或SQL请求执行结果到处到CSV文件。该文件使用UTF-8编码创建。
long DatabaseExport(
int database, //在DatabaseOpen中接收的数据库句柄
const string table_or_sql, // 表格名称或SQL请求
const string filename, // 用于数据导出的CSV文件名称
uint flags, // 标识组合
const string separator // CSV文件中的数据分隔符
);参数
database
[in] 在DatabaseOpen()中接收的数据库句柄。
table_or_sql
[in] 结果将被导出到指定文件的表格名称或SQL请求文本。
filename
[in] 用于数据导出的文件名。设置相对于MQL5\Files文件夹的路径。
flags
[in] ENUM_DATABASE_EXPORT_FLAGS枚举中的标识组合。
separator
[in] 数据分隔符。如果指定NULL,则将'\t'制表符用作分隔符。 空字符串""被认为是有效分隔符,但不能将获取的CSV文件读取为表格 – 它被认为是一组字符串。
返回值
返回导出条目的数量,或者在错误情况下返回负值。要获得错误代码,请使用GetLastError(),可能回应:
- ERR_INTERNAL_ERROR (4001) – 重要运行时错误;
- ERR_INVALID_PARAMETER (4003) – 数据库文件的路径包含空字符串,或设置不兼容的标识组合;
- ERR_NOT_ENOUGH_MEMORY (4004) - 内存不足;
- ERR_FUNCTION_NOT_ALLOWED(4014) – 不允许指定渠道;
- ERR_PROGRAM_STOPPED(4022) – 操作取消(MQL程序停止);
- ERR_WRONG_FILENAME (5002) - 无效文件名;
- ERR_TOO_LONG_FILENAME (5003) - 文件的绝对路径超过最大长度;
- ERR_CANNOT_OPEN_FILE(5004) – 无法打开文件进行编写;
- ERR_FILE_WRITEERROR(5026) – 无法写入文件;
- ERR_DATABASE_INTERNAL (5120) – 内部数据库错误;
- ERR_DATABASE_INVALID_HANDLE (5121) - 无效数据库句柄;
- ERR_DATABASE_QUERY_PREPARE(5125) – 请求生成错误;
- ERR_DATABASE_QUERY_NOT_READONLY – 允许只读请求。
注意
如果请求结果被导出,则SQL请求应该以"SELECT" 或 "select"开始。换句话说,SQL请求不能改变数据库状态,否则DatabaseExport()失败并显示错误。
数据库字符串值可能包含转换字符('\r'或'\r\n' ),以及分隔符参数中设置的值分隔符。在这种情况下,请确保在'flags'参数中使用DATABASE_EXPORT_QUOTED_STRINGS标识。如果该标识已存在,则所有显示的字符串用双引号表示。如果一个字符串包含双引号,则用双层双引号代替。
ENUM_DATABASE_EXPORT_FLAGS
| ID | 描述 |
|---|---|
| DATABASE_EXPORT_HEADER | 在第一个字符串中显示字段名称 |
| DATABASE_EXPORT_INDEX | 显示字符串指数 |
| DATABASE_EXPORT_NO_BOM | 文件开头不要插入BOM掩码(默认插入BOM) |
| DATABASE_EXPORT_CRLF | 用CRLF进行字符串中断(默认为LF) |
| DATABASE_EXPORT_APPEND | 将数据添加到现有文件的末尾(默认情况下,文件被覆盖)。如果文件不存在,则将被创建。 |
| DATABASE_EXPORT_QUOTED_STRINGS | 用双引号显示字符串值。 |
| DATABASE_EXPORT_COMMON_FOLDER | CSV文件在所有客户端的常规文件夹\Terminal\Common\File创建。 |
例如:
input int InpRates=100;
//+------------------------------------------------------------------+
//| 脚本程序起始函数 |
//+------------------------------------------------------------------+
void OnStart()
{
MqlRates rates[];
//--- 记住收到柱形图的开始时间
ulong start=GetMicrosecondCount();
//--- 在H1上请求最后100柱形图
if(CopyRates(Symbol(), PERIOD_H1, 1, InpRates, rates)<InpRates)
{
Print("CopyRates() failed,, Error ", GetLastError());
return;
}
else
{
//--- 接收多少柱形图,以及接收所花费的时间
PrintFormat("%s: CopyRates received %d bars in %d ms ",
_Symbol, ArraySize(rates), (GetMicrosecondCount()-start)/1000);
}
//--- 设置存储数据库的文件名称
string filename=_Symbol+"_"+EnumToString(PERIOD_H1)+"_"+TimeToString(TimeCurrent())+".sqlite";
StringReplace(filename, ":", "-"); // 文件名中不允许使用":"字符
//--- 在常规程序端文件夹中打开/创建数据库
int db=DatabaseOpen(filename, DATABASE_OPEN_READWRITE|DATABASE_OPEN_CREATE|DATABASE_OPEN_COMMON);
if(db==INVALID_HANDLE)
{
Print("Database: ", filename, " open failed with code ", GetLastError());
return;
}
else
Print("Database: ", filename, " opened successfully");
//--- 检查RATES表格是否存在
if(DatabaseTableExists(db, "RATES"))
{
//--- 移除RATES表格
if(!DatabaseExecute(db, "DROP TABLE IF EXISTS RATES"))
{
Print("Failed to drop the RATES table with code ", GetLastError());
DatabaseClose(db);
return;
}
}
//--- 创建RATES表格
if(!DatabaseExecute(db, "CREATE TABLE RATES("
"SYMBOL CHAR(10),"
"TIME INT NOT NULL,"
"OPEN REAL,"
"HIGH REAL,"
"LOW REAL,"
"CLOSE REAL,"
"TICK_VOLUME INT,"
"SPREAD INT,"
"REAL_VOLUME INT);"))
{
Print("DB: ", filename, " create table RATES with code ", GetLastError());
DatabaseClose(db);
return;
}
//--- 显示RATES表格中所有字段列表
if(DatabasePrint(db, "PRAGMA TABLE_INFO(RATES)", 0)<0)
{
PrintFormat("DatabasePrint(\"PRAGMA TABLE_INFO(RATES)\") failed, error code=%d at line %d", GetLastError(), __LINE__);
DatabaseClose(db);
return;
}
//--- 创建参数化请求,将柱形图添加到RATES表格中
string sql="INSERT INTO RATES (SYMBOL,TIME,OPEN,HIGH,LOW,CLOSE,TICK_VOLUME,SPREAD,REAL_VOLUME)"
" VALUES (?1,?2,?3,?4,?5,?6,?7,?8,?9)"; // 请求参数
int request=DatabasePrepare(db, sql);
if(request==INVALID_HANDLE)
{
PrintFormat("DatabasePrepare() failed with code=%d", GetLastError());
Print("SQL request: ", sql);
DatabaseClose(db);
return;
}
//--- 设置第一个请求参数的值
DatabaseBind(request, 0, _Symbol);
//--- 记住将柱形图添加到RATES表格的开始时间
start=GetMicrosecondCount();
DatabaseTransactionBegin(db);
int total=ArraySize(rates);
bool request_error=false;
for(int i=0; i<total; i++)
{
//--- 在添加条目之前设置其余参数的值
ResetLastError();
if(!DatabaseBind(request, 1, rates[i].time))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
//--- 如果之前的DatabaseBind()调用成功,则设置下一个参数
if(!request_error && !DatabaseBind(request, 2, rates[i].open))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
if(!request_error && !DatabaseBind(request, 3, rates[i].high))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
if(!request_error && !DatabaseBind(request, 4, rates[i].low))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
if(!request_error && !DatabaseBind(request, 5, rates[i].close))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
if(!request_error && !DatabaseBind(request, 6, rates[i].tick_volume))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
if(!request_error && !DatabaseBind(request, 7, rates[i].spread))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
if(!request_error && !DatabaseBind(request, 8, rates[i].real_volume))
{
PrintFormat("DatabaseBind() failed with code=%d", GetLastError());
PrintFormat("Bar #%d line=%d", i+1, __LINE__);
request_error=true;
break;
}
//--- 执行插入条目的请求并检查错误
if(!request_error && !DatabaseRead(request) && (GetLastError()!=ERR_DATABASE_NO_MORE_DATA))
{
PrintFormat("DatabaseRead() failed with code=%d", GetLastError());
DatabaseFinalize(request);
request_error=true;
break;
}
//--- 在下一次参数更新之前重置请求
if(!request_error && !DatabaseReset(request))
{
PrintFormat("DatabaseReset() failed with code=%d", GetLastError());
DatabaseFinalize(request);
request_error=true;
break;
}
} //--- 完成检查所有柱形图
//--- 交易事务状态
if(request_error)
{
PrintFormat("Table RATES: failed to add %d bars ", ArraySize(rates));
DatabaseTransactionRollback(db);
DatabaseClose(db);
return;
}
else
{
DatabaseTransactionCommit(db);
PrintFormat("Table RATES: added %d bars in %d ms",
ArraySize(rates), (GetMicrosecondCount()-start)/1000);
}
//--- 将RATES表格保存为CSV文件
string csv_filename=Symbol()+".csv";
long saved=DatabaseExport(db, "SELECT * FROM RATES", csv_filename, DATABASE_EXPORT_HEADER|DATABASE_EXPORT_INDEX|DATABASE_EXPORT_COMMON_FOLDER, ";");
if(saved>0)
Print("Table RATES saved in ", Symbol(), ".csv");
else
Print("DatabaseExport() failed. Error ", GetLastError());
//--- 关闭数据库文件并告知
DatabaseClose(db);
PrintFormat("Database: %s created and closed", filename);