@@ -17,6 +17,11 @@ public partial class Compiler
17
17
protected virtual string LastId { get ; set ; } = "" ;
18
18
protected virtual string EscapeCharacter { get ; set ; } = "\\ " ;
19
19
20
+
21
+ protected virtual string SingleInsertStartClause { get ; set ; } = "INSERT INTO" ;
22
+ protected virtual string MultiInsertStartClause { get ; set ; } = "INSERT INTO" ;
23
+
24
+
20
25
protected Compiler ( )
21
26
{
22
27
_compileConditionMethodsProvider = new ConditionsCompilerProvider ( this ) ;
@@ -391,81 +396,84 @@ protected virtual SqlResult CompileInsertQuery(Query query)
391
396
} ;
392
397
393
398
if ( ! ctx . Query . HasComponent ( "from" , EngineCode ) )
394
- {
395
399
throw new InvalidOperationException ( "No table set to insert" ) ;
396
- }
397
400
398
401
var fromClause = ctx . Query . GetOneComponent < AbstractFrom > ( "from" , EngineCode ) ;
399
-
400
402
if ( fromClause is null )
401
- {
402
403
throw new InvalidOperationException ( "Invalid table expression" ) ;
403
- }
404
404
405
405
string table = null ;
406
-
407
406
if ( fromClause is FromClause fromClauseCast )
408
- {
409
407
table = Wrap ( fromClauseCast . Table ) ;
410
- }
411
-
412
408
if ( fromClause is RawFromClause rawFromClause )
413
409
{
414
410
table = WrapIdentifiers ( rawFromClause . Expression ) ;
415
411
ctx . Bindings . AddRange ( rawFromClause . Bindings ) ;
416
412
}
417
413
418
414
if ( table is null )
419
- {
420
415
throw new InvalidOperationException ( "Invalid table expression" ) ;
421
- }
422
416
423
417
var inserts = ctx . Query . GetComponents < AbstractInsertClause > ( "insert" , EngineCode ) ;
418
+ if ( inserts [ 0 ] is InsertQueryClause insertQueryClause )
419
+ return CompileInsertQueryClause ( ctx , table , insertQueryClause ) ;
420
+ else
421
+ return CompileValueInsertClauses ( ctx , table , inserts . Cast < InsertClause > ( ) ) ;
422
+ }
424
423
425
- if ( inserts [ 0 ] is InsertClause insertClause )
426
- {
427
- var columns = string . Join ( ", " , WrapArray ( insertClause . Columns ) ) ;
428
- var values = string . Join ( ", " , Parameterize ( ctx , insertClause . Values ) ) ;
424
+ protected virtual SqlResult CompileInsertQueryClause (
425
+ SqlResult ctx , string table , InsertQueryClause clause )
426
+ {
427
+ string columns = GetInsertColumnsList ( clause . Columns ) ;
429
428
430
- ctx . RawSql = $ "INSERT INTO { table } ({ columns } ) VALUES ({ values } )";
429
+ var subCtx = CompileSelectQuery ( clause . Query ) ;
430
+ ctx . Bindings . AddRange ( subCtx . Bindings ) ;
431
431
432
- if ( insertClause . ReturnId && ! string . IsNullOrEmpty ( LastId ) )
433
- {
434
- ctx . RawSql += ";" + LastId ;
435
- }
436
- }
437
- else
438
- {
439
- var clause = inserts [ 0 ] as InsertQueryClause ;
432
+ ctx . RawSql = $ "{ SingleInsertStartClause } { table } { columns } { subCtx . RawSql } ";
440
433
441
- var columns = "" ;
434
+ return ctx ;
435
+ }
442
436
443
- if ( clause . Columns . Any ( ) )
444
- {
445
- columns = $ " ( { string . Join ( ", " , WrapArray ( clause . Columns ) ) } ) " ;
446
- }
437
+ protected virtual SqlResult CompileValueInsertClauses (
438
+ SqlResult ctx , string table , IEnumerable < InsertClause > insertClauses )
439
+ {
440
+ bool isMultiValueInsert = insertClauses . Skip ( 1 ) . Any ( ) ;
447
441
448
- var subCtx = CompileSelectQuery ( clause . Query ) ;
449
- ctx . Bindings . AddRange ( subCtx . Bindings ) ;
442
+ var insertInto = ( isMultiValueInsert ) ? MultiInsertStartClause : SingleInsertStartClause ;
450
443
451
- ctx . RawSql = $ "INSERT INTO { table } { columns } { subCtx . RawSql } ";
452
- }
444
+ var firstInsert = insertClauses . First ( ) ;
445
+ string columns = GetInsertColumnsList ( firstInsert . Columns ) ;
446
+ var values = string . Join ( ", " , Parameterize ( ctx , firstInsert . Values ) ) ;
453
447
454
- if ( inserts . Count > 1 )
455
- {
456
- foreach ( var insert in inserts . GetRange ( 1 , inserts . Count - 1 ) )
457
- {
458
- var clause = insert as InsertClause ;
448
+ ctx . RawSql = $ "{ insertInto } { table } { columns } VALUES ({ values } )";
459
449
460
- ctx . RawSql += ", (" + string . Join ( ", " , Parameterize ( ctx , clause . Values ) ) + ")" ;
450
+ if ( isMultiValueInsert )
451
+ return CompileRemainingInsertClauses ( ctx , table , insertClauses ) ;
461
452
462
- }
463
- }
453
+ if ( firstInsert . ReturnId && ! string . IsNullOrEmpty ( LastId ) )
454
+ ctx . RawSql += ";" + LastId ;
464
455
456
+ return ctx ;
457
+ }
465
458
459
+ protected virtual SqlResult CompileRemainingInsertClauses ( SqlResult ctx , string table , IEnumerable < InsertClause > inserts )
460
+ {
461
+ foreach ( var insert in inserts . Skip ( 1 ) )
462
+ {
463
+ string values = string . Join ( ", " , Parameterize ( ctx , insert . Values ) ) ;
464
+ ctx . RawSql += $ ", ({ values } )";
465
+ }
466
466
return ctx ;
467
467
}
468
468
469
+ protected string GetInsertColumnsList ( List < string > columnList )
470
+ {
471
+ var columns = "" ;
472
+ if ( columnList . Any ( ) )
473
+ columns = $ " ({ string . Join ( ", " , WrapArray ( columnList ) ) } )";
474
+
475
+ return columns ;
476
+ }
469
477
470
478
protected virtual SqlResult CompileCteQuery ( SqlResult ctx , Query query )
471
479
{
0 commit comments