@@ -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 ) ;
@@ -361,81 +366,84 @@ protected virtual SqlResult CompileInsertQuery(Query query)
361
366
} ;
362
367
363
368
if ( ! ctx . Query . HasComponent ( "from" , EngineCode ) )
364
- {
365
369
throw new InvalidOperationException ( "No table set to insert" ) ;
366
- }
367
370
368
371
var fromClause = ctx . Query . GetOneComponent < AbstractFrom > ( "from" , EngineCode ) ;
369
-
370
372
if ( fromClause is null )
371
- {
372
373
throw new InvalidOperationException ( "Invalid table expression" ) ;
373
- }
374
374
375
375
string table = null ;
376
-
377
376
if ( fromClause is FromClause fromClauseCast )
378
- {
379
377
table = Wrap ( fromClauseCast . Table ) ;
380
- }
381
-
382
378
if ( fromClause is RawFromClause rawFromClause )
383
379
{
384
380
table = WrapIdentifiers ( rawFromClause . Expression ) ;
385
381
ctx . Bindings . AddRange ( rawFromClause . Bindings ) ;
386
382
}
387
383
388
384
if ( table is null )
389
- {
390
385
throw new InvalidOperationException ( "Invalid table expression" ) ;
391
- }
392
386
393
387
var inserts = ctx . Query . GetComponents < AbstractInsertClause > ( "insert" , EngineCode ) ;
388
+ if ( inserts [ 0 ] is InsertQueryClause insertQueryClause )
389
+ return CompileInsertQueryClause ( ctx , table , insertQueryClause ) ;
390
+ else
391
+ return CompileValueInsertClauses ( ctx , table , inserts . Cast < InsertClause > ( ) ) ;
392
+ }
394
393
395
- if ( inserts [ 0 ] is InsertClause insertClause )
396
- {
397
- var columns = string . Join ( ", " , WrapArray ( insertClause . Columns ) ) ;
398
- var values = string . Join ( ", " , Parameterize ( ctx , insertClause . Values ) ) ;
394
+ protected virtual SqlResult CompileInsertQueryClause (
395
+ SqlResult ctx , string table , InsertQueryClause clause )
396
+ {
397
+ string columns = GetInsertColumnsList ( clause . Columns ) ;
399
398
400
- ctx . RawSql = $ "INSERT INTO { table } ({ columns } ) VALUES ({ values } )";
399
+ var subCtx = CompileSelectQuery ( clause . Query ) ;
400
+ ctx . Bindings . AddRange ( subCtx . Bindings ) ;
401
401
402
- if ( insertClause . ReturnId && ! string . IsNullOrEmpty ( LastId ) )
403
- {
404
- ctx . RawSql += ";" + LastId ;
405
- }
406
- }
407
- else
408
- {
409
- var clause = inserts [ 0 ] as InsertQueryClause ;
402
+ ctx . RawSql = $ "{ SingleInsertStartClause } { table } { columns } { subCtx . RawSql } ";
410
403
411
- var columns = "" ;
404
+ return ctx ;
405
+ }
412
406
413
- if ( clause . Columns . Any ( ) )
414
- {
415
- columns = $ " ( { string . Join ( ", " , WrapArray ( clause . Columns ) ) } ) " ;
416
- }
407
+ protected virtual SqlResult CompileValueInsertClauses (
408
+ SqlResult ctx , string table , IEnumerable < InsertClause > insertClauses )
409
+ {
410
+ bool isMultiValueInsert = insertClauses . Skip ( 1 ) . Any ( ) ;
417
411
418
- var subCtx = CompileSelectQuery ( clause . Query ) ;
419
- ctx . Bindings . AddRange ( subCtx . Bindings ) ;
412
+ var insertInto = ( isMultiValueInsert ) ? MultiInsertStartClause : SingleInsertStartClause ;
420
413
421
- ctx . RawSql = $ "INSERT INTO { table } { columns } { subCtx . RawSql } ";
422
- }
414
+ var firstInsert = insertClauses . First ( ) ;
415
+ string columns = GetInsertColumnsList ( firstInsert . Columns ) ;
416
+ var values = string . Join ( ", " , Parameterize ( ctx , firstInsert . Values ) ) ;
423
417
424
- if ( inserts . Count > 1 )
425
- {
426
- foreach ( var insert in inserts . GetRange ( 1 , inserts . Count - 1 ) )
427
- {
428
- var clause = insert as InsertClause ;
418
+ ctx . RawSql = $ "{ insertInto } { table } { columns } VALUES ({ values } )";
429
419
430
- ctx . RawSql += ", (" + string . Join ( ", " , Parameterize ( ctx , clause . Values ) ) + ")" ;
420
+ if ( isMultiValueInsert )
421
+ return CompileRemainingInsertClauses ( ctx , table , insertClauses ) ;
431
422
432
- }
433
- }
423
+ if ( firstInsert . ReturnId && ! string . IsNullOrEmpty ( LastId ) )
424
+ ctx . RawSql += ";" + LastId ;
434
425
426
+ return ctx ;
427
+ }
435
428
429
+ protected virtual SqlResult CompileRemainingInsertClauses ( SqlResult ctx , string table , IEnumerable < InsertClause > inserts )
430
+ {
431
+ foreach ( var insert in inserts . Skip ( 1 ) )
432
+ {
433
+ string values = string . Join ( ", " , Parameterize ( ctx , insert . Values ) ) ;
434
+ ctx . RawSql += $ ", ({ values } )";
435
+ }
436
436
return ctx ;
437
437
}
438
438
439
+ protected string GetInsertColumnsList ( List < string > columnList )
440
+ {
441
+ var columns = "" ;
442
+ if ( columnList . Any ( ) )
443
+ columns = $ " ({ string . Join ( ", " , WrapArray ( columnList ) ) } )";
444
+
445
+ return columns ;
446
+ }
439
447
440
448
protected virtual SqlResult CompileCteQuery ( SqlResult ctx , Query query )
441
449
{
0 commit comments