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
|
||||
((ServerVersionInt >= 50604) and (not Parameters.IsMariaDB)) then 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;
|
||||
end;
|
||||
end;
|
||||
@ -2644,13 +2644,20 @@ begin
|
||||
DataType := Cols.Col('DATA_TYPE');
|
||||
DataType := DataType.ToUpper.DeQuotedString('"');
|
||||
Result := Result + CRLF + #9 + QuoteIdent(Cols.Col('COLUMN_NAME')) + ' ' + DataType;
|
||||
MaxLen := '';
|
||||
if not Cols.IsNull('CHARACTER_MAXIMUM_LENGTH') then begin
|
||||
MaxLen := Cols.Col('CHARACTER_MAXIMUM_LENGTH');
|
||||
if MaxLen = '-1' then
|
||||
Result := Result + '(max)'
|
||||
else
|
||||
Result := Result + '(' + MaxLen + ')';
|
||||
MaxLen := 'max';
|
||||
end else if not Cols.IsNull('NUMERIC_PRECISION') then begin
|
||||
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;
|
||||
if not MaxLen.IsEmpty then
|
||||
Result := Result + '(' + MaxLen + ')';
|
||||
if Cols.Col('IS_NULLABLE') = 'NO' then
|
||||
Result := Result + ' NOT';
|
||||
Result := Result + ' NULL';
|
||||
@ -3827,32 +3834,10 @@ end;
|
||||
|
||||
|
||||
function TDBConnection.GetDateTimeValue(Input: String; Datatype: TDBDatatypeIndex): String;
|
||||
var
|
||||
dt: TDateTime;
|
||||
begin
|
||||
// Return date/time string value as expected by server
|
||||
case Parameters.NetTypeGroup of
|
||||
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;
|
||||
end;
|
||||
end;
|
||||
else
|
||||
Result := Input;
|
||||
end;
|
||||
// Not sure why there was a conversion required in earlier versions.
|
||||
Result := Input;
|
||||
end;
|
||||
|
||||
|
||||
@ -5554,6 +5539,8 @@ begin
|
||||
case Datatype(Column).Category of
|
||||
dtcReal:
|
||||
Result := FloatToStr(FCurrentResults.Fields[Column].AsExtended, FFormatSettings);
|
||||
dtcTemporal:
|
||||
Result := FormatDateTime(Datatype(Column).Format, FCurrentResults.Fields[Column].AsFloat);
|
||||
else
|
||||
Result := FCurrentResults.Fields[Column].AsString;
|
||||
end;
|
||||
@ -5792,9 +5779,10 @@ begin
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
if idx = -1 then
|
||||
raise EDatabaseError.CreateFmt(_('Column "%s" not available.'), [Column]);
|
||||
Result := IsNull(idx);
|
||||
if idx > -1 then
|
||||
Result := IsNull(idx)
|
||||
else
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ uses
|
||||
Windows, Forms, Graphics, Messages, VirtualTrees, ComCtrls, SysUtils, Classes,
|
||||
StdCtrls, ExtCtrls, CheckLst, Controls, Types, Dialogs, Menus, Mask, DateUtils, Math,
|
||||
dbconnection, mysql_structures, helpers, texteditor, bineditor, gnugettext,
|
||||
StrUtils, System.UITypes;
|
||||
StrUtils, System.UITypes, SynRegExpr;
|
||||
|
||||
type
|
||||
// Radio buttons and checkboxes which do not pass <Enter> key to their parent control
|
||||
@ -562,7 +562,7 @@ begin
|
||||
case FTableColumn.DataType.Index of
|
||||
dtDate:
|
||||
FMaskEdit.EditMask := '0000-00-00;1; ';
|
||||
dtDatetime, dtTimestamp, dtInt, dtBigint: begin
|
||||
dtDatetime, dtDatetime2, dtTimestamp, dtInt, dtBigint: begin
|
||||
if MicroSecondsPrecision > 0 then
|
||||
FMaskEdit.EditMask := '0000-00-00 00\:00\:00.'+StringOfChar('0', MicroSecondsPrecision)+';1; '
|
||||
else
|
||||
@ -738,7 +738,7 @@ begin
|
||||
text := DateToStr(d);
|
||||
end;
|
||||
|
||||
dtDateTime, dtTimestamp, dtInt, dtBigint: begin
|
||||
dtDateTime, dtDateTime2, dtTimestamp, dtInt, dtBigint: begin
|
||||
dt := StrToDateTime(FMaskEdit.Text);
|
||||
case FMaskEdit.SelStart of
|
||||
0..3: dt := IncYear(dt, Offset);
|
||||
@ -803,8 +803,22 @@ end;
|
||||
|
||||
|
||||
function TDateTimeEditorLink.MicroSecondsPrecision: Integer;
|
||||
var
|
||||
rx: TRegExpr;
|
||||
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
|
||||
if FTableColumn.DataType.Index in [dtInt, dtBigint] then
|
||||
Result := 0;
|
||||
|
@ -183,7 +183,7 @@ type
|
||||
// MySQL data types
|
||||
TDBDatatypeIndex = (dtTinyint, dtSmallint, dtMediumint, dtInt, dtBigint, dtSerial, dtBigSerial,
|
||||
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,
|
||||
dtBinary, dtVarbinary, dtTinyblob, dtBlob, dtMediumblob, dtLongblob, dtImage,
|
||||
dtEnum, dtSet, dtBit, dtVarBit, dtBool, dtJson, dtUnknown,
|
||||
@ -207,6 +207,7 @@ type
|
||||
HasBinary: Boolean; // Can be binary?
|
||||
HasDefault: Boolean; // Can have a default value?
|
||||
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;
|
||||
end;
|
||||
|
||||
@ -403,6 +404,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy-mm-dd';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -417,6 +419,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -434,6 +437,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -449,6 +453,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -466,6 +471,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -941,6 +947,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -953,6 +960,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy-mm-dd';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -963,16 +971,18 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy-mm-dd hh:nn:ss.zzz';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
Index: dtDatetime;
|
||||
Index: dtDatetime2;
|
||||
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.';
|
||||
HasLength: False;
|
||||
HasLength: True;
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy-mm-dd hh:nn:ss.zzzzzzz';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -983,6 +993,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: True;
|
||||
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -1329,6 +1340,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: False;
|
||||
Format: 'yyyy-mm-dd';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -1340,6 +1352,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: False;
|
||||
Format: 'hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -1352,6 +1365,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: False;
|
||||
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -1363,6 +1377,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: False;
|
||||
Format: 'yyyy-mm-dd';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
@ -1374,6 +1389,7 @@ var
|
||||
RequiresLength: False;
|
||||
HasBinary: False;
|
||||
HasDefault: False;
|
||||
Format: 'yyyy-mm-dd hh:nn:ss';
|
||||
Category: dtcTemporal;
|
||||
),
|
||||
(
|
||||
|
Reference in New Issue
Block a user