You are not logged in.
The table:
CREATE TABLE CustInv (
ID INTEGER PRIMARY KEY AUTOINCREMENT,
...
);
The view:
CREATE VIEW v_event_inv AS
SELECT header.ID AS DocId,
...
FROM CustInv header
The delphi code:
var
myFieldType: TSQLFieldType;
myFieldTypeName: string;
myFieldValue: string;
tmpTable: TSQLTableJSON;
begin
tmpTable := AppCtx.Db.ExecuteList([], 'SELECT * FROM v_event_inv');
//some testing code
{$IFDEF DEBUG}
myFieldType := tmpTable.FieldType(0);//expected: sftID. Actual: sftFloat
myFieldTypeName := GetEnumName(TypeInfo(TSQLFieldType), Integer(myFieldType));
myFieldValue := tmpTable.FieldValue('DocId', 1); //correct
CodeSite.Send(myFieldValue, myFieldTypeName);
{$ENDIF}
PS: I noticed the bug after using ToClientDataSet, but tracked it down in ExecuteList()...
Last edited by edwinsn (2015-09-29 16:47:46)
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
A sample JSON response I got while debugging this issue:
[{"DocId":2078946242580065800,"DocDate":"2015-09-15","EventType":"e_po","ProductNr":"000020"}]
note 1: the DocId value is long...
note 2: I'm using the latest version from github.
Last edited by edwinsn (2015-09-29 17:15:03)
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Default is a fast "guess" from the actual JSON content, which may be not exact in such cases.
You have to force the expected field types in tmpTable, using TSQLTable.SetFieldType() method.
Online
Thanks ab, I'll utilize the SetFieldType method. I'm curious - doesn't the sqlite engine return field type info for the result set?
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Yes, it does, but there is no SQL field type returned within the JSON response from the server.
Just values are returned, not types.
So TSQLTableJson has to guess the field type from actual values (with some potential errors), unless TSQLTable.SetFieldType() method is used.
Online
So do you have a plan to fix it?
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
IMHO, the JSON response returned from the server should include the field type info.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
REST is about transmission per representation.
There is never low-level information like "backend DB column types" in the JSON transmitted in such REST services.
The field type info would not be included with the JSON data.
Online
REST is about transmission per representation.
There is never low-level information like "backend DB column types" in the JSON transmitted in such REST services.
The field type info would not be included with the JSON data.
If you want to have the type information, use a DB-based technology, like SynDBRemote.
Online
But even working in REST mode, SQL has its advantage and we need to execute complex SQL to generate reports.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
I do not see what is the problem here.
If you generate a report, you know the result layout of the JSON generated by your SQL, so you can define the field types before using it in a TDataSet.
Online
Hi Arnaud,
Yes, I can solve the problem that way. But I still tend to think the ExecuteList() should either correctly determine all field types or the user have to manually set type for all fields, otherwise it's error-prone.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
May be add an additional question about metadata, and answer receive in JSON?
Offline
Passing such big numbers in JSON is not good solution IMHO. In case your service is used from browser it will lose precision during json.parse. Internally in JavaScript numbers are double. In my services I either limit a int64 values to 10^16 or pass it as string if limitation is not possible
Offline
It is error prone only if you do not use the ORM, but SQL and TDataSet...
Yes, but I guess it's very common to use SQL directly for complex reports that require multiple level of joins even union joins.
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline
Passing such big numbers in JSON is not good solution IMHO. In case your service is used from browser it will lose precision during json.parse. Internally in JavaScript numbers are double. In my services I either limit a int64 values to 10^16 or pass it as string if limitation is not possible
Thanks MPV, I'm not using it in the browser, but that seems a limit of JS, is there a way to get around it, like treating the IDs as strings?
Delphi XE4 Pro on Windows 7 64bit.
Lazarus trunk built with fpcupdelux on Windows with cross-compile for Linux 64bit.
Offline