mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Limit rows per exported INSERT to 1000 for MSSQL. Introduced MaxRowsPerInsert property per connection type. 10000 for all other types. Closes #1189
This commit is contained in:
@ -411,6 +411,7 @@ type
|
||||
FForeignKeyQueriesFailed: Boolean;
|
||||
FInfSch: String;
|
||||
FIdentCharsNoQuote: TSysCharSet;
|
||||
FMaxRowsPerInsert: Int64;
|
||||
procedure SetActive(Value: Boolean); virtual; abstract;
|
||||
procedure DoBeforeConnect; virtual;
|
||||
procedure DoAfterConnect; virtual;
|
||||
@ -529,6 +530,7 @@ type
|
||||
function GetTableColumns(Table: TDBObject): TTableColumnList; virtual;
|
||||
function GetTableKeys(Table: TDBObject): TTableKeyList; virtual;
|
||||
function GetTableForeignKeys(Table: TDBObject): TForeignKeyList; virtual;
|
||||
property MaxRowsPerInsert: Int64 read FMaxRowsPerInsert;
|
||||
published
|
||||
property Active: Boolean read FActive write SetActive default False;
|
||||
property Database: String read FDatabase write SetDatabase;
|
||||
@ -1772,6 +1774,7 @@ begin
|
||||
FInformationSchemaObjects.CaseSensitive := False;
|
||||
// Characters in identifiers which don't need to be quoted
|
||||
FIdentCharsNoQuote := ['A'..'Z', 'a'..'z', '0'..'9', '_'];
|
||||
FMaxRowsPerInsert := 10000;
|
||||
end;
|
||||
|
||||
|
||||
@ -1802,6 +1805,7 @@ begin
|
||||
for i:=0 to High(MSSQLDatatypes) do
|
||||
FDatatypes[i] := MSSQLDatatypes[i];
|
||||
FInfSch := 'INFORMATION_SCHEMA';
|
||||
FMaxRowsPerInsert := 1000;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -454,8 +454,6 @@ var
|
||||
IsEncl, IsTerm, IsLineTerm, IsEof: Boolean;
|
||||
InEncl: Boolean;
|
||||
OutStream: TMemoryStream;
|
||||
const
|
||||
MaxRowCountPerChunk = 1000;
|
||||
|
||||
procedure NextChar;
|
||||
begin
|
||||
@ -552,7 +550,7 @@ const
|
||||
StreamWrite(OutStream, SQL + ')');
|
||||
SQL := '';
|
||||
Inc(RowCountInChunk);
|
||||
if (OutStream.Size < PacketSize) and (P < ContentLen) and (RowCountInChunk < MaxRowCountPerChunk) then begin
|
||||
if (OutStream.Size < PacketSize) and (P < ContentLen) and (RowCountInChunk < FConnection.MaxRowsPerInsert) then begin
|
||||
SQL := SQL + ', (';
|
||||
end else begin
|
||||
OutStream.Position := 0;
|
||||
|
@ -1440,10 +1440,12 @@ end;
|
||||
|
||||
procedure TfrmTableTools.DoExport(DBObj: TDBObject);
|
||||
var
|
||||
IsFirstRowInChunk, NeedsDBStructure: Boolean;
|
||||
NeedsDBStructure: Boolean;
|
||||
InsertSizeExceeded, RowLimitExceeded: Boolean;
|
||||
Struc, Header, DbDir, FinalDbName, BaseInsert, Row, TargetDbAndObject, BinContent, tmp: String;
|
||||
i: Integer;
|
||||
RowCount, Limit, Offset, ResultCount: Int64;
|
||||
RowCount, RowCountInChunk: Int64;
|
||||
Limit, Offset, ResultCount: Int64;
|
||||
StartTime: Cardinal;
|
||||
StrucResult, Data: TDBQuery;
|
||||
ColumnList: TTableColumnList;
|
||||
@ -1735,11 +1737,11 @@ begin
|
||||
BaseInsert := BaseInsert + ') VALUES'+CRLF+#9+'(';
|
||||
while true do begin
|
||||
Output(BaseInsert, False, True, True, True, True);
|
||||
IsFirstRowInChunk := True;
|
||||
RowCountInChunk := 0;
|
||||
|
||||
while not Data.Eof do begin
|
||||
Row := '';
|
||||
if not IsFirstRowInChunk then
|
||||
if RowCountInChunk > 0 then
|
||||
Row := Row + ','+CRLF+#9+'(';
|
||||
for i:=0 to Data.ColumnCount-1 do begin
|
||||
if Data.ColIsVirtual(i) then
|
||||
@ -1767,12 +1769,13 @@ begin
|
||||
Delete(Row, Length(Row)-1, 2);
|
||||
Row := Row + ')';
|
||||
// Break if stream would increase over the barrier of 1MB, and throw away current row
|
||||
if (not IsFirstRowInChunk)
|
||||
and (ExportStream.Size - ExportStreamStartOfQueryPos + Length(Row) > updownInsertSize.Position*SIZE_KB*0.9)
|
||||
then
|
||||
break;
|
||||
InsertSizeExceeded := ExportStream.Size - ExportStreamStartOfQueryPos + Length(Row) > updownInsertSize.Position*SIZE_KB*0.9;
|
||||
// Same with MSSQL which is limited to 1000 rows per INSERT
|
||||
RowLimitExceeded := RowCountInChunk >= Quoter.MaxRowsPerInsert;
|
||||
if (RowCountInChunk > 0) and (InsertSizeExceeded or RowLimitExceeded) then
|
||||
Break;
|
||||
Inc(RowCount);
|
||||
IsFirstRowInChunk := False;
|
||||
Inc(RowCountInChunk);
|
||||
Output(Row, False, True, True, True, True);
|
||||
Data.Next;
|
||||
end;
|
||||
|
Reference in New Issue
Block a user