Delphi XE7 MultiDevice SQL Error TIMESTAMP Ret. Field - mysql

I've an SQLTIMESTAMP binded (SQL output of query from datamodule)
(On live bindings) -> BindVIsually TTMFSMXGRID.
When I open the query, the field is correctly filled in the grid (EX: 06/05/2016, etc)
But when I try to take the Cell[x,y] as StringToSqltimestamp it come back in a different format (WRONG FORMAT). And I am trying to use field for a query so it make me an error (EOF) because don't find anything in that date.
dm1.UpdMsg.ParamByName('data').AsSQLTimeStamp:=StrToSQLTimeStamp(GrRec.Cells[1,GrRec.FocusedCell.Row]);
Any idea about how to solve it?

Like other date/time formatting functions, StrToSqlTimeStamp() by default uses formatting criteria based on the current system locale. If that does not match what you need (for example, maybe the day and month are swapped), you can use the overloaded version that accepts a TFormatSettings as input so you can customize it.
var
Fmt: TFormatSettings;
begin
// Get default settings first...
Fmt := TFormatSettings.Create;
// customize Fmt as needed...
Fmt.ShortDateFormat := 'dd/mm/yyyy';
Fmt.DateSeparator := '/';
// not convert...
dm1.UpdMsg.ParamByName('data').AsSQLTimeStamp := StrToSQLTimeStamp(GrRec.Cells[1,GrRec.FocusedCell.Row], Fmt);
end;

Related

Talend could not parse column as timestamp

I need your help in this issue,
I have a talend job which load data from a table to another with a simple tmap.
I called it a mysterious error because it happended just for a specific datetimes
java.sql.SQLException: Could not parse column as timestamp, was: "2009-06-01 00:00:00"
Thousands of rows before the row containing this line doesn't generate the error
When I modify this date 2009-06-01 00:00:00 to another or just changing the day part or the month or even the hour, It goes without error.
the datasource is a mariadb and the destination is a Mysql database
thnks for your help
and this is the part of code which contain the error generated
if (colQtyInRs_tMysqlInput_5 < 6) {
row5.created_at = null;
} else {
if (rs_tMysqlInput_5.getString(6) != null) {
String dateString_tMysqlInput_5 = rs_tMysqlInput_5
.getString(6);
if (!("0000-00-00")
.equals(dateString_tMysqlInput_5)
&& !("0000-00-00 00:00:00")
.equals(dateString_tMysqlInput_5)) {
row5.created_at = rs_tMysqlInput_5
.getTimestamp(6);
} else {
row5.created_at = (java.util.Date) year0_tMysqlInput_5
.clone();
}
} else {
row5.created_at = null;
}
}
Since you provided no further information in
How the source data looks like, e.g. is it a date field or a string field in the source?
Why parsing would happen, this seems to be connected to the source data being a string
How the parsing pattern looks like
I am going to assume a bit here.
1st: I assume you provide a string in the source. Since this is the case, you'd need to make sure that the date in the column is always formatted the same way. Also, you'd need to show us the timestamp format for parsing.
2nd: You said you'd need to change the values of the date for it to work. This seems to me to be an issue with parsing, so for example you have switched by accident the month and day field, e.g. yyyy-dd-mm HH:mm:ss or something alike. Again, this depends on your parsing string.
Since there is often a bit of confusion about this I created a blog post for date handling in Talend which you could consult as well.
This error is due to Timezone, after trying many solutions, I thought about changing the timezone because My Laptop is in UTC and the database timezone is UTC+01 so Talend generate this error in local environment.
Hope it will help someone else

DBGrid / DataSet fails to sort as per sql statement set in CommandText

I'm using the following in my CommandText property of the DataSet I'm using:
SELECT *
FROM table_name
ORDER BY FIELD(priority, 'urgent', 'normal'),
FIELD(state, 'wait', 'executed', 'done')
It should sort the data I'm displaying in the DBGrid connected to this DataSet, like this:
Rows containing urgent in the priority column should start the DBGrid list.
Then the list should continue with the ones marked as normal in the priority column,
followed by the ones marked as wait in the state column,
followed by the ones marked as executed in the state column,
and finally the list ends with the ones marked as done in the state column.
But It doesn't, well actually it kind of does, but it's actually backwards.
Here is a quick video I've made to show you whats happening, maybe you can get a clearer view this way:
Video of what's happening
I'm guessing it's because of either the ID column I'm using or the Date column but if so, I have no idea how and why.
This is how those 2 columns look like/are set up:
ID column is set as Primary and Unique and Auto_Increment - that's it, no Index or any of the other options
If it's not those 2 columns the problem, then maybe the DBGrid?
I'm using RAD Studio 10 Seattle, dbExpress components (TSimpleDataSet, etc) and MySQL db
Any thoughts on how to fix this? thanks!
You are making life unnecessarily difficult for yourself going about it the way you are.
It's not necessary to get the server to do the sorting (by using an ORDER BY clause and it's arguably better to do the sorting in the client rather than on the server, because the client typically has computing power to spare whereas the server may not.
So, this is my suggested way of going about it:
Drop the ORDER BY from your SQL and just do a a SELECT * [...].
Replace your SimpleDataSet by a ClientDataSet and define persistent TFields on it. The reason for making this change is so as to be able to create two persistent fields of type fkInternalCalc.
In the TFields editor in the Object Inspector, define two fkInternalCalc fields called something like PriorityCode and StateCode.
Set the IndexFieldNames property of your dataset to 'PriorityCode;StateCode'.
In the OnCalcFields event of your dataset, calculate values for the PriorityCode and StateCode that will give the sort order you wish the data rows to have.
Something like:
procedure TForm1.ClientDataSet1CalcFields(DataSet: TDataSet);
var
S : String;
PriorityCodeField,
StateCodeField : TField;
iValue : Integer;
begin
PriorityCodeField := ClientDataset1.FieldByName('PriorityCode');
StateCodeField := ClientDataset1.FieldByName('StateCode');
S := ClientDataset1.FieldByName('Priority').AsString;
if S = 'urgent' then
iValue := 1
else
if S = 'normal' then
iValue := 2
else
iValue := 999;
PriorityCodeField.AsInteger := iValue;
S := ClientDataset1.FieldByName('State').AsString;
if S = 'wait' then
iValue := 1
else
if S = 'executed' then
iValue := 2
else
if S = 'done' then
iValue := 3
else
iValue := 999;
StateCodeField.AsInteger := iValue;
end;
Actually, it would be better (faster, less overhead) if you avoid using FieldByName and just use the fields that the Fields that the OI's Tfields editor creates, since these will be automatically bound to the ClientDataSet's data fields when it is opened.
Btw, it's useful to bear in mind that although a TClientDataSet cannot be sorted on a field defined in the TFields editor as Calculated, it can be sorted on an InternalCalc field.

Delphi datatype for SQL Server last_user_update

The SQL Server code below returns the time-date of the last update to a table (any row.)
SELECT OBJECT_NAME(OBJECT_ID) AS DatabaseName, last_user_update
FROM sys.dm_db_index_usage_stats
WHERE OBJECT_ID=OBJECT_ID('TableName')
AND (Index_ID = 1)
If I use this in a TFDQuery, what is the datatype FDQuery1.FieldByName('last_user_update')?
If I want to store and compare this value at different times in a Delphi variable, what Delphi datatype should I assign it to, Double?
You use a TDateTime for this.
Although the TDateTime is represented internally by a double you don't use a double because you'll miss out on all the date/time support.
The code goes like this.
var
LastUpdate: TDateTime;
begin
//Do query etc.
...
LastUpdate:= MyQuery.FieldByName('last_user_update').AsDateTime;
Note that SQL server 7 and before do not have support for TDate. So if you just want the date part this code will fail in SQL server 7.
LastUpdate:= MyQuery.FieldByName('last_user_update').AsDate;
Just get the full DateTime and strip of the Time part later.
However, you're working with 2008 so just extracting the date will work fine for you.
Here's a list of DateTime functions: http://www.delphibasics.co.uk/ByFunction.asp?Main=DatesAndTimes

MySQL CONCAT returns incorrect result when used with variable in Dbeaver

Is there any known issue about using variables in CONCAT or am I making a mistake in below query?
set #m := '2016';
select concat('2015','-',#m);
Expected result is 2015-2016, but strangely it returns
2015F201
I tested many other variations with and without using variables, it works as expected without variables, but return similiar 'unexpected' results when used with variables.
I'm using DBeaver as SQL client, it somehow thinks that the result of that query is binary:
select concat('2015','-',#m);
and show it incorrectly: 2015F201 (not exactly hexadecimal)
When I change settings under Preferences window, Common / Result Sets / Binaries / Binary Data formatter to String, it shows correctly.

Filtering Dates in FireDac TTable

I'm having a problem using TTable in FireDac to filter on a date field.
The database in MySQL/InnoDB. The field is of type Date.
The code I am using to set the filter is
Filter := 'date = ' + QuotedStr(FormatDateTime('mm/dd/yyyy', Date));
Filtered := True;
Every time I either get an error when setting the filter: "EConvertError with message 'Could not parse SQL TimeStamp string'" or the filter fails to find any records.
The above format is for my current regional settings. I've also tried 'yyyy-mm-dd'. And I've tried both both with and without quotes.
So, I spend three hours on this and immediately after I ask the question I find an answer. Use Preprocessor Commands:
Filter := 'date = {d ' + (FormatDateTime('yyyy-mm-dd', Date))+'}';