From 8beb135a504dfc59941086a693eff9dbc5860b78 Mon Sep 17 00:00:00 2001 From: Ansgar Becker Date: Wed, 17 Sep 2025 16:51:15 +0200 Subject: [PATCH] Issue #2250: use N(ational) prefix in MS SQL for any text value going through the second version of EscapeString(), supporting Unicode now when importing a file into a table. --- source/dbconnection.pas | 25 ++++++++++--------------- source/loaddata.pas | 6 +++--- source/tabletools.pas | 2 +- 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/source/dbconnection.pas b/source/dbconnection.pas index d93acee7..2fccd764 100644 --- a/source/dbconnection.pas +++ b/source/dbconnection.pas @@ -5308,6 +5308,11 @@ begin end; end; Result := EscapeString(Text, False, DoQuote); + + // Support international characters with National prefix on MSSQL, see #1115 and #2250. + // Previously only done in some callers of the other version of EscapeString(), and only for column types dbdtNchar, dbdtNvarchar, dbdtNtext. + if FParameters.IsAnyMSSQL and (Datatype.Category = dtcText) then + Result := 'N' + Result; end; @@ -9908,14 +9913,10 @@ begin end; dtcBinary, dtcSpatial: Val := FConnection.EscapeBin(Cell.NewText); - else begin - if Datatype(i).Index in [dbdtNchar, dbdtNvarchar, dbdtNtext] then - Val := 'N' + Connection.EscapeString(Cell.NewText) - else if Datatype(i).Category = dtcTemporal then - Val := Connection.EscapeString(Connection.GetDateTimeValue(Cell.NewText, Datatype(i).Index)) - else - Val := Connection.EscapeString(Cell.NewText); - end; + dtcTemporal: + Val := Connection.EscapeString(Connection.GetDateTimeValue(Cell.NewText, Datatype(i).Index)) + else + Val := Connection.EscapeString(Cell.NewText, Datatype(i)); end; sqlUpdate := sqlUpdate + Connection.QuoteIdent(FColumnOrgNames[i]) + '=' + Val; sqlInsertColumns := sqlInsertColumns + Connection.QuoteIdent(FColumnOrgNames[i]); @@ -10301,13 +10302,7 @@ begin Result := Result + '=' + FConnection.EscapeBin(ColVal); else begin // Any other data type goes here, including text: - case DataType(j).Index of - // Support international characters with N-prefix on MSSQL, see #1115: - dbdtNchar, dbdtNvarchar, dbdtNtext: - Result := Result + '=N' + Connection.EscapeString(ColVal); - else - Result := Result + '=' + Connection.EscapeString(ColVal); - end; + Result := Result + '=' + Connection.EscapeString(ColVal, DataType(j)); end; end; end; diff --git a/source/loaddata.pas b/source/loaddata.pas index e329f5a3..899dc80e 100644 --- a/source/loaddata.pas +++ b/source/loaddata.pas @@ -526,9 +526,9 @@ var for i:=0 to chkListColumns.Items.Count-1 do begin if chkListColumns.Checked[i] then // column was already counted - Inc(ValuesCounted); // increase number of counted columns + Inc(ValuesCounted); // increase number of counted columns if ValuesCounted = ValueCount then // did we count all included columns up to the current column? - Break; + Break; Inc(ColumnIndex); // if all columns (until the current column) are checked, ColumnIndex is ValueCount-1, like before this patch end; @@ -536,7 +536,7 @@ var if chkLocalNumbers.Checked and (FColumns[ColumnIndex].DataType.Category in [dtcInteger, dtcReal]) then Value := UnformatNumber(Value) else - Value := FConnection.EscapeString(Value); + Value := FConnection.EscapeString(Value, FColumns[ColumnIndex].DataType); end; SQL := SQL + Value + ', '; end; diff --git a/source/tabletools.pas b/source/tabletools.pas index f5d8dcfd..0a4a478c 100644 --- a/source/tabletools.pas +++ b/source/tabletools.pas @@ -2120,7 +2120,7 @@ begin else Row := Row + Quoter.EscapeString(''); end; - else Row := Row + Quoter.EscapeString(Data.Col(i)); + else Row := Row + Quoter.EscapeString(Data.Col(i), Data.DataType(i)); end; Row := Row + ', '; end;