Use FireDAC to MSSQL Server in parallel(std::vector<std::thread>)[JAPAN]
std::thread exists.It is in the standard from C++11.
Insert data in MS-SQL Server in this way.
The data is a Japanese address CSV. that is,
It is in the post office in Japan web site.
The data looks something like this.
"0600000","北海道","札幌市 中央区","以下に掲載がない場合","HOKKAIDO","SAPPORO SHI CHUO KU","IKANIKEISAIGANAIBAAI" "0640941","北海道","札幌市 中央区","旭ケ丘","HOKKAIDO","SAPPORO SHI CHUO KU","ASAHIGAOKA" "0600041","北海道","札幌市 中央区","大通東","HOKKAIDO","SAPPORO SHI CHUO KU","ODORIHIGASHI"
It is a CSV mixed with Japanese.
To insert with TFDQuery,TFDConnection, do this.
//// inline static void sql_add(String sql_values) { CoInitialize(nullptr); try { std::unique_ptr<TFDConnection> fdc_{std::make_unique<TFDConnection>(nullptr)}; std::unique_ptr<TFDQuery> query_{std::make_unique<TFDQuery>(nullptr)}; try { fdc_->DriverName = "MSSQL"; fdc_->LoginPrompt = false; fdc_->Params->Append("Server=localhost"); fdc_->Params->Append("User_Name=sa"); fdc_->Params->Append("Password=test"); fdc_->Params->Append("Database=dbname"); fdc_->Params->Append("DriverID=MSSQL"); fdc_->Connected = true; query_->Connection = fdc_.get(); query_->SQL->Text = sql_values; std::cout << (static_cast<AnsiString>(sql_values)).c_str() << "\n"; query_->ExecSQL(); } catch(...){} } __finally { CoUninitialize(); } }
Read "CSV File" and loop processing.This is making 5 threads.
I used std::thread, but I think that System.Threading.TTask is also good.
//// void load_csv(String csv_filename , std::function<void(String)> aproc) { std::unique_ptr<TStringList> csv =std::make_unique<TStringList>(); try { int count_{0}; csv->LoadFromFile(csv_filename, System::Sysutils::TEncoding::ANSI); for (int i=0; i < csv->Count; i++) { //aproc(csv->Strings[i]); std::vector<std::thread> v1; v1.clear(); for (int th_count = 0; th_count < 5; th_count++) { if ((i+th_count) < csv->Count) { String line_ = csv->Strings[i+th_count]; v1.push_back(std::thread([&](){aproc(line_);})); } } for (auto th_= v1.begin(); th_!=v1.end(); th_++) { th_->join(); } Sleep(100); i +=4; } for (AnsiString line: csv.get()) { count_++; } } catch(...){} }
It is a function calling "void load_csv(String csv_filename , std::function<void(String)> aproc)" and lambda.
//// void start() { load_csv("C:\\Embarcadero\\ado_zip_insert\\KEN_ALL_ROME_test.CSV", [&](String aline){ String sql_; std::wstringstream cols_; std::wstring value_; try { cols_.str(StringReplace(aline,L"\"", "",TReplaceFlags()<<rfReplaceAll).w_str()); while (std::getline(cols_, value_, L',')){ sql_ = sql_ + "'" + value_.c_str() + "',"; }; sql_add( Format(L"insert into T_ZIP values(%s, getdate())", ARRAYOFCONST(( sql_.Delete(sql_.Length(), 1) ))) ); } catch(...){} } ); }
Call on the main.
//// #include <FireDAC.Comp.Client.hpp> #include <FireDAC.Comp.DataSet.hpp> #include <FireDAC.DApt.hpp> #include <FireDAC.DApt.Intf.hpp> #include <FireDAC.DatS.hpp> #include <FireDAC.Phys.hpp> #include <FireDAC.Phys.Intf.hpp> #include <FireDAC.Phys.MSSQL.hpp> #include <FireDAC.Phys.MSSQLDef.hpp> #include <FireDAC.Stan.Async.hpp> #include <FireDAC.Stan.Def.hpp> #include <FireDAC.Stan.Error.hpp> #include <FireDAC.Stan.Intf.hpp> #include <FireDAC.Stan.Option.hpp> #include <FireDAC.Stan.Param.hpp> #include <FireDAC.Stan.Pool.hpp> #include <functional> #include <memory> #include <sstream> #include <thread> #include <vector>
//// namespace yubin_postoffice_japan { struct Tmssql_import { Tmssql_import() { start(); } ~Tmssql_import(){} inline static void sql_add(String sql_values) void load_csv(String csv_filename , std::function<void(String)> aproc) void start() }; }
It is a project of console application.
//// int _tmain(int argc, _TCHAR* argv[]) { using namespace yubin_postoffice_japan; TDateTime dtTemp{Now()}; Tmssql_import(); String out = "elapsed time "+FormatDateTime("hh:nn:ss.zzz", Now() - dtTemp); std::cout << out.c_str() << std::endl; OutputDebugString(out.w_str()); return 0; }


Delphi / C++Builder blogger
Comments
-
Please login first in order for you to submit comments