From static to dynamic statements
July 26, 2025 ยท View on GitHub
From static to dynamic statements
See also custom statements
Fully static
The most straight forward use of sqlpp23 is by constructing and running static statements, e.g.
for (const auto& row : db(select(foo.id, foo.name, foo.hasFun)
.from(foo)
.where(foo.id > 17)))
{
// Do something with
// - row.id
// - row.name
// - row.hasFun
}
In this example, selected columns are fixed (foo.id, foo.name,
foo.hasFun), they belong to exactly one table (foo), and the condition
definitely compares the id with a number (17).
Using variables
Values like 17 can be replaced by variables to provide a bit of flexibility:
int64_t min_id = some_value;
// ...
for (const auto& row : db(select(foo.id, foo.name, foo.hasFun)
.from(foo)
.where(foo.id > min_id)))
{
// ...
}
Using prepared statements with parameters
Prepared statements with parameters provide similar flexibility as statements with variables but at a later stage (after preparing the statement in the database backend).
auto prepared_select = db.prepare(select(foo.id, foo.name, foo.hasFun)
.from(foo)
.where(foo.id > parameter(foo.id)));
prepared_select.id = 17;
for (const auto& row : db(prepared_select))
{
// ...
}
prepared_select.id = 18;
for (const auto& row : db(prepared_select))
{
// ...
}
dynamic
What if you wanted to do some modifications at runtime? Maybe there is a blob
that we might want to read under some condition? We can use dynamic components
for this. Let's take a look at an example:
bool maybe = some_condition;
// ...
for (const auto& row : db(select(foo.id,
foo.name,
foo.hasFun,
dynamic(maybe, bar.blobX))
.from(foo.join(dynamic(maybe, bar))
.on(foo.barId == bar.id))
.where(foo.id > 17 and
dynamic(maybe, bar.blob.is_not_null())))) {
// In addition to id, name and hasFun, row also has a member called blobX.
// If `maybe` is false, blobX is always `nullopt`.
}
Depending on the value of maybe the structure of the statement changes at
runtime:
- If
maybe == true, the statement will select an additional column (bar.blobX), joinfoowithbaron the given condition and add another condition to thewhereclause. - If
maybe == false, the statement will almost be the same as the static version above. The only difference is that the result rows will contain a column calledblobXof typeblobwhich will containnullopt.
[!IMPORTANT] sqlpp23's ability to validate statements is reduced if
dynamicis used.
- It can check that static components do not depend on dynamic components. In
the example above, it you could not select
bar.blobXwithout wrapping it into adynamiccall becausebaris joined dynamically, only. - If you are using multiple
dynamiccomponents, the library cannot check if the conditions match. For instance, you could join on one condition and add a column with another. This might end up in incorrect statements.