mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
* Fix microseconds in MSSQL date/time data types, hidden in data and query grids.
* Add support for microsecond precision of MSSQL date/time types in table editor, show these in "Length/Set" column * See http://www.heidisql.com/forum.php?t=17728
This commit is contained in:
@ -2111,7 +2111,7 @@ begin
|
|||||||
if ((ServerVersionInt >= 50300) and Parameters.IsMariaDB) or
|
if ((ServerVersionInt >= 50300) and Parameters.IsMariaDB) or
|
||||||
((ServerVersionInt >= 50604) and (not Parameters.IsMariaDB)) then begin
|
((ServerVersionInt >= 50604) and (not Parameters.IsMariaDB)) then begin
|
||||||
for i:=Low(FDatatypes) to High(FDatatypes) do begin
|
for i:=Low(FDatatypes) to High(FDatatypes) do begin
|
||||||
if FDatatypes[i].Index in [dtDatetime, dtTime, dtTimestamp] then
|
if FDatatypes[i].Index in [dtDatetime, dtDatetime2, dtTime, dtTimestamp] then
|
||||||
FDatatypes[i].HasLength := True;
|
FDatatypes[i].HasLength := True;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2644,13 +2644,20 @@ begin
|
|||||||
DataType := Cols.Col('DATA_TYPE');
|
DataType := Cols.Col('DATA_TYPE');
|
||||||
DataType := DataType.ToUpper.DeQuotedString('"');
|
DataType := DataType.ToUpper.DeQuotedString('"');
|
||||||
Result := Result + CRLF + #9 + QuoteIdent(Cols.Col('COLUMN_NAME')) + ' ' + DataType;
|
Result := Result + CRLF + #9 + QuoteIdent(Cols.Col('COLUMN_NAME')) + ' ' + DataType;
|
||||||
|
MaxLen := '';
|
||||||
if not Cols.IsNull('CHARACTER_MAXIMUM_LENGTH') then begin
|
if not Cols.IsNull('CHARACTER_MAXIMUM_LENGTH') then begin
|
||||||
MaxLen := Cols.Col('CHARACTER_MAXIMUM_LENGTH');
|
MaxLen := Cols.Col('CHARACTER_MAXIMUM_LENGTH');
|
||||||
if MaxLen = '-1' then
|
if MaxLen = '-1' then
|
||||||
Result := Result + '(max)'
|
MaxLen := 'max';
|
||||||
else
|
end else if not Cols.IsNull('NUMERIC_PRECISION') then begin
|
||||||
Result := Result + '(' + MaxLen + ')';
|
MaxLen := Cols.Col('NUMERIC_PRECISION');
|
||||||
|
if not Cols.IsNull('NUMERIC_SCALE') then
|
||||||
|
MaxLen := MaxLen + ',' + Cols.Col('NUMERIC_SCALE');
|
||||||
|
end else if not Cols.IsNull('DATETIME_PRECISION') then begin
|
||||||
|
MaxLen := Cols.Col('DATETIME_PRECISION');
|
||||||
end;
|
end;
|
||||||
|
if not MaxLen.IsEmpty then
|
||||||
|
Result := Result + '(' + MaxLen + ')';
|
||||||
if Cols.Col('IS_NULLABLE') = 'NO' then
|
if Cols.Col('IS_NULLABLE') = 'NO' then
|
||||||
Result := Result + ' NOT';
|
Result := Result + ' NOT';
|
||||||
Result := Result + ' NULL';
|
Result := Result + ' NULL';
|
||||||
@ -3827,33 +3834,11 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
function TDBConnection.GetDateTimeValue(Input: String; Datatype: TDBDatatypeIndex): String;
|
function TDBConnection.GetDateTimeValue(Input: String; Datatype: TDBDatatypeIndex): String;
|
||||||
var
|
|
||||||
dt: TDateTime;
|
|
||||||
begin
|
begin
|
||||||
// Return date/time string value as expected by server
|
// Return date/time string value as expected by server
|
||||||
case Parameters.NetTypeGroup of
|
// Not sure why there was a conversion required in earlier versions.
|
||||||
ngMSSQL: begin
|
|
||||||
try
|
|
||||||
dt := StrToDateTime(Input);
|
|
||||||
case Datatype of
|
|
||||||
dtDate:
|
|
||||||
Result := SysUtils.FormatDateTime('yyyy"-"mm"-"dd', dt);
|
|
||||||
dtTime:
|
|
||||||
Result := SysUtils.FormatDateTime('hh":"nn":"ss', dt);
|
|
||||||
dtYear:
|
|
||||||
Result := SysUtils.FormatDateTime('yyyy', dt);
|
|
||||||
dtDatetime:
|
|
||||||
Result := SysUtils.FormatDateTime('yyyy"-"mm"-"dd hh":"nn":"ss', dt);
|
|
||||||
end;
|
|
||||||
except
|
|
||||||
on E:EConvertError do
|
|
||||||
Result := Input;
|
Result := Input;
|
||||||
end;
|
end;
|
||||||
end;
|
|
||||||
else
|
|
||||||
Result := Input;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -5554,6 +5539,8 @@ begin
|
|||||||
case Datatype(Column).Category of
|
case Datatype(Column).Category of
|
||||||
dtcReal:
|
dtcReal:
|
||||||
Result := FloatToStr(FCurrentResults.Fields[Column].AsExtended, FFormatSettings);
|
Result := FloatToStr(FCurrentResults.Fields[Column].AsExtended, FFormatSettings);
|
||||||
|
dtcTemporal:
|
||||||
|
Result := FormatDateTime(Datatype(Column).Format, FCurrentResults.Fields[Column].AsFloat);
|
||||||
else
|
else
|
||||||
Result := FCurrentResults.Fields[Column].AsString;
|
Result := FCurrentResults.Fields[Column].AsString;
|
||||||
end;
|
end;
|
||||||
@ -5792,9 +5779,10 @@ begin
|
|||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if idx = -1 then
|
if idx > -1 then
|
||||||
raise EDatabaseError.CreateFmt(_('Column "%s" not available.'), [Column]);
|
Result := IsNull(idx)
|
||||||
Result := IsNull(idx);
|
else
|
||||||
|
Result := True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ uses
|
|||||||
Windows, Forms, Graphics, Messages, VirtualTrees, ComCtrls, SysUtils, Classes,
|
Windows, Forms, Graphics, Messages, VirtualTrees, ComCtrls, SysUtils, Classes,
|
||||||
StdCtrls, ExtCtrls, CheckLst, Controls, Types, Dialogs, Menus, Mask, DateUtils, Math,
|
StdCtrls, ExtCtrls, CheckLst, Controls, Types, Dialogs, Menus, Mask, DateUtils, Math,
|
||||||
dbconnection, mysql_structures, helpers, texteditor, bineditor, gnugettext,
|
dbconnection, mysql_structures, helpers, texteditor, bineditor, gnugettext,
|
||||||
StrUtils, System.UITypes;
|
StrUtils, System.UITypes, SynRegExpr;
|
||||||
|
|
||||||
type
|
type
|
||||||
// Radio buttons and checkboxes which do not pass <Enter> key to their parent control
|
// Radio buttons and checkboxes which do not pass <Enter> key to their parent control
|
||||||
@ -562,7 +562,7 @@ begin
|
|||||||
case FTableColumn.DataType.Index of
|
case FTableColumn.DataType.Index of
|
||||||
dtDate:
|
dtDate:
|
||||||
FMaskEdit.EditMask := '0000-00-00;1; ';
|
FMaskEdit.EditMask := '0000-00-00;1; ';
|
||||||
dtDatetime, dtTimestamp, dtInt, dtBigint: begin
|
dtDatetime, dtDatetime2, dtTimestamp, dtInt, dtBigint: begin
|
||||||
if MicroSecondsPrecision > 0 then
|
if MicroSecondsPrecision > 0 then
|
||||||
FMaskEdit.EditMask := '0000-00-00 00\:00\:00.'+StringOfChar('0', MicroSecondsPrecision)+';1; '
|
FMaskEdit.EditMask := '0000-00-00 00\:00\:00.'+StringOfChar('0', MicroSecondsPrecision)+';1; '
|
||||||
else
|
else
|
||||||
@ -738,7 +738,7 @@ begin
|
|||||||
text := DateToStr(d);
|
text := DateToStr(d);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
dtDateTime, dtTimestamp, dtInt, dtBigint: begin
|
dtDateTime, dtDateTime2, dtTimestamp, dtInt, dtBigint: begin
|
||||||
dt := StrToDateTime(FMaskEdit.Text);
|
dt := StrToDateTime(FMaskEdit.Text);
|
||||||
case FMaskEdit.SelStart of
|
case FMaskEdit.SelStart of
|
||||||
0..3: dt := IncYear(dt, Offset);
|
0..3: dt := IncYear(dt, Offset);
|
||||||
@ -803,8 +803,22 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
function TDateTimeEditorLink.MicroSecondsPrecision: Integer;
|
function TDateTimeEditorLink.MicroSecondsPrecision: Integer;
|
||||||
|
var
|
||||||
|
rx: TRegExpr;
|
||||||
begin
|
begin
|
||||||
Result := MakeInt(FTableColumn.LengthSet);
|
if not FTableColumn.LengthSet.IsEmpty then
|
||||||
|
Result := MakeInt(FTableColumn.LengthSet)
|
||||||
|
else begin
|
||||||
|
// Find default length of supported microseconds in datatype definition
|
||||||
|
// See mysql_structures
|
||||||
|
rx := TRegExpr.Create;
|
||||||
|
rx.Expression := '\.([^\.]+)$';
|
||||||
|
if rx.Exec(FTableColumn.DataType.Format) then
|
||||||
|
Result := rx.MatchLen[1]
|
||||||
|
else
|
||||||
|
Result := 0;
|
||||||
|
rx.Free;
|
||||||
|
end;
|
||||||
// No microseconds for UNIX timestamp columns
|
// No microseconds for UNIX timestamp columns
|
||||||
if FTableColumn.DataType.Index in [dtInt, dtBigint] then
|
if FTableColumn.DataType.Index in [dtInt, dtBigint] then
|
||||||
Result := 0;
|
Result := 0;
|
||||||
|
@ -183,7 +183,7 @@ type
|
|||||||
// MySQL data types
|
// MySQL data types
|
||||||
TDBDatatypeIndex = (dtTinyint, dtSmallint, dtMediumint, dtInt, dtBigint, dtSerial, dtBigSerial,
|
TDBDatatypeIndex = (dtTinyint, dtSmallint, dtMediumint, dtInt, dtBigint, dtSerial, dtBigSerial,
|
||||||
dtFloat, dtDouble, dtDecimal, dtNumeric, dtReal, dtDoublePrecision, dtMoney, dtSmallmoney,
|
dtFloat, dtDouble, dtDecimal, dtNumeric, dtReal, dtDoublePrecision, dtMoney, dtSmallmoney,
|
||||||
dtDate, dtTime, dtYear, dtDatetime, dtSmalldatetime, dtTimestamp, dtInterval,
|
dtDate, dtTime, dtYear, dtDatetime, dtDatetime2, dtSmalldatetime, dtTimestamp, dtInterval,
|
||||||
dtChar, dtNchar, dtVarchar, dtNvarchar, dtTinytext, dtText, dtNtext, dtMediumtext, dtLongtext,
|
dtChar, dtNchar, dtVarchar, dtNvarchar, dtTinytext, dtText, dtNtext, dtMediumtext, dtLongtext,
|
||||||
dtBinary, dtVarbinary, dtTinyblob, dtBlob, dtMediumblob, dtLongblob, dtImage,
|
dtBinary, dtVarbinary, dtTinyblob, dtBlob, dtMediumblob, dtLongblob, dtImage,
|
||||||
dtEnum, dtSet, dtBit, dtVarBit, dtBool, dtJson, dtUnknown,
|
dtEnum, dtSet, dtBit, dtVarBit, dtBool, dtJson, dtUnknown,
|
||||||
@ -207,6 +207,7 @@ type
|
|||||||
HasBinary: Boolean; // Can be binary?
|
HasBinary: Boolean; // Can be binary?
|
||||||
HasDefault: Boolean; // Can have a default value?
|
HasDefault: Boolean; // Can have a default value?
|
||||||
DefLengthSet: String; // Should be set for types which require a length/set
|
DefLengthSet: String; // Should be set for types which require a length/set
|
||||||
|
Format: String; // Used for date/time values when displaying and generating queries
|
||||||
Category: TDBDatatypeCategoryIndex;
|
Category: TDBDatatypeCategoryIndex;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -403,6 +404,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy-mm-dd';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -417,6 +419,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -434,6 +437,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -449,6 +453,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -466,6 +471,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -941,6 +947,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -953,6 +960,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy-mm-dd';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -963,16 +971,18 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy-mm-dd hh:nn:ss.zzz';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Index: dtDatetime;
|
Index: dtDatetime2;
|
||||||
Name: 'DATETIME2';
|
Name: 'DATETIME2';
|
||||||
Description: 'Date and time data from January 1,1 AD through December 31, 9999 AD, with an accuracy of three-hundredths of a second, or 3.33 milliseconds.';
|
Description: 'Date and time data from January 1,1 AD through December 31, 9999 AD, with an accuracy of three-hundredths of a second, or 3.33 milliseconds.';
|
||||||
HasLength: False;
|
HasLength: True;
|
||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy-mm-dd hh:nn:ss.zzzzzzz';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -983,6 +993,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: True;
|
HasDefault: True;
|
||||||
|
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -1329,6 +1340,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: False;
|
HasDefault: False;
|
||||||
|
Format: 'yyyy-mm-dd';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -1340,6 +1352,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: False;
|
HasDefault: False;
|
||||||
|
Format: 'hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -1352,6 +1365,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: False;
|
HasDefault: False;
|
||||||
|
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -1363,6 +1377,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: False;
|
HasDefault: False;
|
||||||
|
Format: 'yyyy-mm-dd';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -1374,6 +1389,7 @@ var
|
|||||||
RequiresLength: False;
|
RequiresLength: False;
|
||||||
HasBinary: False;
|
HasBinary: False;
|
||||||
HasDefault: False;
|
HasDefault: False;
|
||||||
|
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||||
Category: dtcTemporal;
|
Category: dtcTemporal;
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
Reference in New Issue
Block a user