insertSelect method
Future<MssqlWriteOutcome>
insertSelect({
- required List<
String> columns, - required MssqlSelectQuery query,
- List<
MssqlCte> ctes = const <MssqlCte>[],
INSERT … SELECT, with the statement's WITH clause where T-SQL wants
it: at the very start, before INSERT.
Returns the driver's count rather than a captured one. A set-based insert has no single row to read back, and counting its output rows would mean materialising the whole set on the client for a number the caller can also get from the target table.
Implementation
Future<MssqlWriteOutcome> insertSelect({
required List<String> columns,
required MssqlSelectQuery query,
List<MssqlCte> ctes = const <MssqlCte>[],
}) async {
for (final name in columns) {
final column = binding.column(name);
if (column == null) {
throw ArgumentError.value(
name,
'columns',
'Names a column ${binding.qualifiedName} does not have.',
);
}
if (!column.writable) {
throw ArgumentError.value(
name,
'columns',
column.isReadOnly
? 'Is marked read-only by the generator configuration.'
: 'Is written by the server (identity, computed or rowversion), '
'so a projected value has nowhere to land.',
);
}
}
var insert = MssqlInsert.intoParts(binding.nameParts).using(columns, query);
for (final cte in ctes) {
insert = insert.withExpression(cte);
}
final statement = insert.compile(dialect: dialect);
if (triggers == MssqlTriggerKind.none) {
return _executeCounted(statement.sql, statement.parameters);
}
final affected = await session.execute(
statement.sql,
parameters: statement.parameters,
);
_note();
return MssqlWriteOutcome(
affectedRows: affected,
affectedRowsSource: MssqlAffectedRowsSource.driverTotal,
);
}