@@ -64,6 +64,9 @@ You must have either $a or $d
6464 " , Mandatory = true , DefaultValue = "$c_$d" ) ]
6565 public string TableNamingPattern { get ; set ; }
6666
67+ [ DemandsInitialization ( "How long should the merge command be allowed to run before timing out, in seconds" , DefaultValue = 30000 ) ]
68+ public int SQLMergeTimeout { get ; set ; }
69+
6770
6871 private DiscoveredDatabase db ;
6972 private DataTable _toProcess ;
@@ -163,7 +166,7 @@ protected override void Open(DataTable toProcess, IDataLoadEventListener job, Gr
163166
164167 protected override void WriteRows ( DataTable toProcess , IDataLoadEventListener job , GracefulCancellationToken cancellationToken , Stopwatch stopwatch )
165168 {
166- _toProcess = toProcess ;
169+ _toProcess = toProcess ;
167170 var discoveredServer = DataAccessPortal . ExpectServer ( TargetDatabaseServer , DataAccessContext . DataExport , false ) ;
168171
169172 //sort out the naming
@@ -182,7 +185,7 @@ protected override void WriteRows(DataTable toProcess, IDataLoadEventListener jo
182185 db . Create ( ) ;
183186
184187
185- var tableName = GetTableName ( null , toProcess ) ;
188+ var tableName = GetTableName ( null , toProcess ) ;
186189 var destinationTable = db . ExpectTable ( tableName ) ;
187190
188191 //ensure there are some pks
@@ -254,10 +257,11 @@ protected override void WriteRows(DataTable toProcess, IDataLoadEventListener jo
254257 //merge
255258 var tmpTbl = db . CreateTable (
256259 out Dictionary < string , Guesser > _dataTypeDictionary ,
257- $ "mergeTempTable_{ tableName } _{ DateTime . Now . ToString ( "yyyy-MM-dd HH:mm:ss.fff" , CultureInfo . InvariantCulture ) . Replace ( '.' , '-' ) } ",
258- toProcess , null , true , null ) ;
260+ $ "mergeTempTable_{ tableName } _{ DateTime . Now . ToString ( "yyyy-MM-dd HH:mm:ss.fff" , CultureInfo . InvariantCulture ) . Replace ( '.' , '-' ) } ",
261+ toProcess , null , true , null ) ;
259262 var _managedConnection = tmpTbl . Database . Server . GetManagedConnection ( ) ;
260263 var _bulkcopy = tmpTbl . BeginBulkInsert ( CultureInfo . CurrentCulture , _managedConnection . ManagedTransaction ) ;
264+ _bulkcopy . Timeout = SQLMergeTimeout ;
261265 _bulkcopy . Upload ( toProcess ) ;
262266 _bulkcopy . Dispose ( ) ;
263267 var mergeSql = $ """
@@ -268,17 +272,18 @@ WHEN MATCHED THEN
268272 UPDATE SET { string . Join ( " , " , nonPkColumns . Select ( pkc => $ "target.{ pkc . ColumnName } = source.{ pkc . ColumnName } ") ) }
269273 WHEN NOT MATCHED BY TARGET THEN
270274 INSERT ({ string . Join ( " , " , toProcess . Columns . Cast < DataColumn > ( ) . Select ( pkc => pkc . ColumnName ) ) } )
271- VALUES ({ string . Join ( " , " , toProcess . Columns . Cast < DataColumn > ( ) . Select ( pkc => $ "source.{ pkc . ColumnName } ") ) } ){ ( AllowMergeToPerformDeletes ? "" : ";" ) }
272- { ( AllowMergeToPerformDeletes ? """
275+ VALUES ({ string . Join ( " , " , toProcess . Columns . Cast < DataColumn > ( ) . Select ( pkc => $ "source.{ pkc . ColumnName } ") ) } ){ ( AllowMergeToPerformDeletes ? "" : ";" ) }
276+ { ( AllowMergeToPerformDeletes ? """
273277 WHEN NOT MATCHED BY SOURCE THEN
274278 DELETE;
275- """ : "" ) }
279+ """ : "" ) }
276280 """ ;
277281 job . OnNotify ( this , new NotifyEventArgs ( ProgressEventType . Information , $ "{ mergeSql } ") ) ;
278282 var cmd = new SqlCommand ( mergeSql , ( SqlConnection ) _managedConnection . Connection ) ;
283+ cmd . CommandTimeout = SQLMergeTimeout ;
279284 var rowCount = cmd . ExecuteNonQuery ( ) ;
280285 job . OnNotify ( this , new NotifyEventArgs ( ProgressEventType . Information , $ "Merged { rowCount } rows into { destinationTable . GetFullyQualifiedName ( ) } .") ) ;
281- if ( DeleteMergeTempTable ) tmpTbl . Drop ( ) ;
286+ if ( DeleteMergeTempTable ) tmpTbl . Drop ( ) ;
282287 _managedConnection . Dispose ( ) ;
283288 }
284289
0 commit comments