In the manual of the packagage datatool just read about \DTLnewdbonloadtrue and \DTLnewdbonloadfalse:
By default, \DTLloaddb creates a new database called ⟨db name⟩ before it loads the data given in the file ⟨filename⟩. If you want to append the data, use
\DTLnewdbonloadfalse
before you use \DTLloaddb. You can reverse this using
\DTLnewdbonloadtrue
\documentclass{article}
\usepackage{datatool}
\DTLsetseparator{;}
%dbA
\begin{filecontents}{databaseA.csv}
first; second
A; B
C; D
E; F
\end{filecontents}
%dbB
\begin{filecontents}{databaseB.csv}
first; second
G; H
I; J
K; L
M; N
\end{filecontents}
%dbC
\begin{filecontents}{databaseC.csv}
first; second
O; P
\end{filecontents}
\makeatletter
\newcommand\LoadNoMoreDatabases{\LoadNoMoreDatabases}%
\newcommand\LoadDatabases[1]{\DTLnewdbonloadtrue\LoadDatabasesLoop{\DTLnewdbonloadfalse}{#1}}
\newcommand\LoadDatabasesLoop[3]{%
% #1 tokens to execute after \DTLloadrawdb
% #2 name of database
% #3 name of csv-file or end-marker for the loop.
\ifx\LoadNoMoreDatabases#3\expandafter@secondoftwo\else\expandafter@firstoftwo\fi
{\DTLloadrawdb{#2}{#3}#1\LoadDatabasesLoop{}{#2}}%
{\DTLnewdbonloadtrue}%
}%
\makeatother
% Syntax of the mechanism:
%
% \LoadDatabases{<database to create>}{<csv-file 1>}{<csv-file 2>}...{<csv-file k>}\LoadNoMoreDatabases
\LoadDatabases{db}{databaseA.csv}{databaseB.csv}{databaseC.csv}\LoadNoMoreDatabases
\begin{document}
\DTLdisplaydb{db}
\end{document}

The above does
\DTLnewdbonloadtrue
\DTLloadrawdb{⟨database to create⟩}{⟨csv-file 1⟩}%
\DTLnewdbonloadfalse
\DTLloadrawdb{⟨database to create⟩}{⟨csv-file 2⟩}%
\DTLloadrawdb{⟨database to create⟩}{⟨csv-file 3⟩}%
...
\DTLloadrawdb{⟨database to create⟩}{⟨csv-file k-1⟩}%
\DTLloadrawdb{⟨database to create⟩}{⟨csv-file k⟩}%
\DTLnewdbonloadtrue
You can easily use \clist_map_inline:nn of expl3's l3clist-package for creating a macro where you can pass a comma-list of filenames.
\documentclass{article}
\usepackage{xparse}
\usepackage{datatool}
\DTLsetseparator{;}
%dbA
\begin{filecontents}{databaseA.csv}
first; second
A; B
C; D
E; F
\end{filecontents}
%dbB
\begin{filecontents}{databaseB.csv}
first; second
G; H
I; J
K; L
M; N
\end{filecontents}
%dbC
\begin{filecontents}{databaseC.csv}
first; second
O; P
\end{filecontents}
\ExplSyntaxOn
\NewDocumentCommand\LoadDatabases{mm}{
\DTLnewdb{#1} % <- create the new empty database
\DTLnewdbonloadfalse % <- let's append to that database
\clist_map_inline:nn {#2} {\DTLloadrawdb{#1}{##1}} % <- have a sequence of calls `\DTLloadrawdb
\DTLnewdbonloadtrue % <- switch back to \DTLload(raw)db not appending to an existing database but to creating databases anew.
}
\ExplSyntaxOff
\LoadDatabases{db}{databaseA.csv, databaseB.csv, databaseC.csv}
\begin{document}
\DTLdisplaydb{db}
\end{document}

Explanation of the code:
Release 2021-08-27 of The LaTeX3 Interfaces says in section 22.5 Mapping over comma lists:
\clist_map_inline:Nn
\clist_map_inline:cn
\clist_map_inline:nn
Updated: 2012-06-29
\clist_map_inline:Nn ⟨comma list⟩ {⟨inline function⟩}
Applies ⟨inline function⟩ to every
⟨item⟩ stored within the ⟨comma list⟩. The ⟨inline function⟩ should
consist of code which receives the ⟨item⟩ as #1.
The ⟨items⟩ are returned from left to right.
The last sentence of this explanation seems a bit inaccurate to me, because what is returned is not only the items. What is returned are as many sequences of tokens as there are non-blank items in the ⟨comma list⟩. Each sequence of tokens consists of that assortment of tokens that is called ⟨inline function⟩, whereby in that assortment the sequence #1 is replaced by those tokens, of which the respective item consists.
After defining
\NewDocumentCommand\LoadDatabases{mm}{
\DTLnewdb{#1}
\DTLnewdbonloadfalse
\clist_map_inline:nn {#2} {\DTLloadrawdb{#1}{##1}}
\DTLnewdbonloadtrue
}
the sequence \LoadDatabase{db}{databaseA.csv, databaseB.csv, databaseC.csv}
yields:
\DTLnewdb{db}
\DTLnewdbonloadfalse
\clist_map_inline:nn {databaseA.csv, databaseB.csv, databaseC.csv} {\DTLloadrawdb{db}{#1}}
\DTLnewdbonloadtrue
(During the expansion of \LoadDatabases the two consecutive hashes ## of ##1 collapse into a single hash#.)
\clist_map_inline:nn's ⟨comma list⟩ is: databaseA.csv, databaseB.csv, databaseC.csv
\clist_map_inline:nn's ⟨inline function⟩ is: \DTLloadrawdb{db}{#1}
Within the ⟨inline function⟩ #1 denotes an item of the ⟨comma list⟩, i.e., the name of a .csv-file.
So \clist_map_inline:nn yields something like
\DTLloadrawdb{db}{databaseA.csv}%
\DTLloadrawdb{db}{databaseB.csv}%
\DTLloadrawdb{db}{databaseC.csv}%
.csvfiles and add missing rows? – Werner Sep 05 '21 at 20:55