You are not logged in.
Pages: 1
Enable a transaction during the batch.
Hi DB I did what you suggested, but I got another trouble. When i enable a transcation during the bact for every 5 rows the application stop / hang when it tries to save the 2nd object, the table may be locked confilict. My Database is MS SQL Server. I can not execute query for this table until i shutdown my application.
I Think mormot fail to rollback transaction.
Enable a transaction during the batch.
How to do it AB ?
Should I change my code to :
Batch := TSQLRestBatch.Create(RestServer, TMorAssetSplit, 5);
try
AAssetSplit.IDValue := 10000; // I do it on purpose to get Error
Batch.Add(AAssetSplit, True, True);
Batch.Add(AAssetSplit, True, True); // I do it on purpose to get Error
RestServer.BatchSend(Batch);
finally
Batch.Free;
end;
OK, Solved ! Thank you all
How to rollback transaction when it fails to execute BatchSend menthod in server side. Here is my code :
Batch := TSQLRestBatch.Create(RestServer, TMorAssetSplit);
try
AAssetSplit.IDValue := 10000; // I do it on purpose to get Error
Batch.Add(AAssetSplit, True, True);
Batch.Add(AAssetSplit, True, True); // I do it on purpose to get Error
RestServer.BatchSend(Batch);
finally
Batch.Free;
end;
I execute the above code on server. It generates error when trying to save the 2nd AAssetSplit because it has same ID (10000). But when i check in database, the frist AAssetSplit is Saved. How to rollback transaction in batch processing ?
You can force the ID, using an incremental integer on the server side, or TSynUniqueIdentifier if you want something unique over a network.
Hi AB, how to Force ID if ID is readonly property ?
Thanks
Hi edwinsn thank you for your quick response.
I did it using "batch mode" also. But I got trouble when TFahter has property refers to TChildren. Everytime I save those objects, field Children in table TFather is always "0". I don't know how to use "batch mode" in this case.
Thanks
Hi, I have 2 objects of TSQLRecord (TFahter and TChildren). I Want to save both in the same time. How should I do it ? How to define Transcation and commit ?
Thank You
one more addition, before using mormot + Interbase, we must create domain BIGINT. Here is the code
create domain BIGINT as Integer
I have solved the above error. I change unit unit mORMotDB.pas
function TSQLRestStorageExternal.CreateSQLMultiIndex(
Table: TSQLRecordClass; const FieldNames: array of RawUTF8;
Unique: boolean; IndexName: RawUTF8): boolean;
var SQL: RawUTF8;
ExtFieldNames: TRawUTF8DynArray;
IntFieldIndex: TIntegerDynArray;
Descending: boolean;
i,n,extfield: integer;
begin
..........................................
dPostgreSQL,dMSSQL,dMySQL,dOracle,dNexusDB: begin // as most DB on primary key
result := true;
exit;
end;
dFirebird: // see http://www.firebirdfaq.org/faq205
Descending := true;
end;
.........................................
tobe
function TSQLRestStorageExternal.CreateSQLMultiIndex(
Table: TSQLRecordClass; const FieldNames: array of RawUTF8;
Unique: boolean; IndexName: RawUTF8): boolean;
var SQL: RawUTF8;
ExtFieldNames: TRawUTF8DynArray;
IntFieldIndex: TIntegerDynArray;
Descending: boolean;
i,n,extfield: integer;
begin
.........................................
dPostgreSQL,dMSSQL,dMySQL,dOracle,dNexusDB, dFirebird: begin // as most DB on primary key
result := true;
exit;
end;
// dFirebird: // see http://www.firebirdfaq.org/faq205
// Descending := true;
end;
.........................................
hello AB, i have solved the above error. But i got another error. Here is the error log :
20160902 07582138 ! + SynDBFireDAC.TSQLDBFireDACStatement(01BB5A00).007ED1A9
20160902 07582138 ! SQL SynDBFireDAC.TSQLDBFireDACStatement(01BB5A00) CREATE UNIQUE DESC INDEX NDXMorAssetID ON MorAsset(ID)
20160902 07582447 ! EXC EIBNativeException ("[FireDAC][Phys][IB]unsuccessful metadata update\r\nSTORE RDB$INDICES failed\r\nattempt to store duplicate value (visible to active transactions) in unique index \"RDB$INDEX_5\"") at 00721C9F stack trace API 00544E02
20160902 07582447 ! EXC EIBNativeException ("[FireDAC][Phys][IB]unsuccessful metadata update\r\nSTORE RDB$INDICES failed\r\nattempt to store duplicate value (visible to active transactions) in unique index \"RDB$INDEX_5\"") at 00721C9F stack trace API 00544E02
20160902 07582447 ! EXC EIBNativeException ("[FireDAC][Phys][IB]unsuccessful metadata update\r\nSTORE RDB$INDICES failed\r\nattempt to store duplicate value (visible to active transactions) in unique index \"RDB$INDEX_5\"") at 00721C9F stack trace API 00544E02
20160902 07582447 ! EXC EIBNativeException ("[FireDAC][Phys][IB]unsuccessful metadata update\r\nSTORE RDB$INDICES failed\r\nattempt to store duplicate value (visible to active transactions) in unique index \"RDB$INDEX_5\"") at 00721C9F stack trace API 00544E02 004071EC 77B7718B 77B77017 00721C9F 00AF9238 00B0B394 00B0B521 007BE47F 007BE5B7 007BF5AF 007BE00E 0084100A 00841460 007B915C 007BF89C 00828D9B 0082906D 0082F52D 007F8DEE 0084352D 00607884 00607F6F 005B3EBD 005B416A 0059D133 006C367E 00B0E168 004990F5 0049D44D
20160902 07582448 ! EXC EIBNativeException ("[FireDAC][Phys][IB]unsuccessful metadata update\r\nSTORE RDB$INDICES failed\r\nattempt to store duplicate value (visible to active transactions) in unique index \"RDB$INDEX_5\"") at 00721C9F stack trace API 00544E02
20160902 07582449 ! EXC EIBNativeException ("[FireDAC][Phys][IB]unsuccessful metadata update\r\nSTORE RDB$INDICES failed\r\nattempt to store duplicate value (visible to active transactions) in unique index \"RDB$INDEX_5\"") at 00721C9F stack trace API 00544E02
20160902 07582449 ! EXC EIBNativeException ("[FireDAC][Phys][IB]unsuccessful metadata update\r\nSTORE RDB$INDICES failed\r\nattempt to store duplicate value (visible to active transactions) in unique index \"RDB$INDEX_5\"") at 00721C9F stack trace API 00544E02
Could you point me which part of this framework to be changed ?
Hello, I have tried mormot in SQL Server and PostgreSQL. On those DBMS, mormot runs smoothly. But, when i change dbms to Interbase i got error. It's error is caused by execution of SQL
select first 1 ID from tablename
In interbase, if we want to get firstrow of a table the sql is :
select ID from tablename rows 1
How to fix this error ?
Hi ,
Sometimes (not always) I get error
[FireDAC][Phys][PG][libpq] ERROR: DECLARE CURSOR can only be used in transaction blocks
. After executing Add / AddOrUpdate of TSQLHttpClient , then i execute "select query" and get the above error.
here is my logs :
SynDBFireDAC.TSQLDBFireDACStatement(02F19110) select ID,AccountAccDep,Category,Company,DateCreated,AIN,AssetStatus,AssetType,Nama,AccountAssetAP,Address,Description,Employee,Entity,Ownership,Parent,SN from public.Asset where ID=5
20160822 02012829 B EXC EPgNativeException ("[FireDAC][Phys][PG][libpq] ERROR: DECLARE CURSOR can only be used in transaction blocks") at 00712D13 stack trace API 00539786
I get this error when using PostgresSQL, but get no error when using Ms SQL Server.
Has any body found workwround of this error ?
Thank you AB,
I Agree with you. I would NEVER expose such a query to browsers. I just want to test execute my method on browser.
Hi ....
I have interface based service in server. The code :
IRemoteSQL = interface(IInvokable)
['{0E34DC10-0A32-4A19-97E4-8012E06D32AA}']
function ExecuteSQL(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
end;
How to execute function ExecuteSQL using browser ?
Hi AB I did what you say. The result is OK :). Here is my code :
Server Side
Interface
IRemoteSQL = interface(IInvokable)
['{0E34DC10-0A32-4A19-97E4-8012E06D32AA}']
function Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean): RawJSON;
end;
TServiceRemoteSQL = class(TInterfacedObject, IRemoteSQL)
protected
public
destructor Destroy; override;
public
function Execute(const aSQL: RawUTF8; aExpectResults, aExpanded: Boolean):
RawJSON;
end;
implementation
destructor TServiceRemoteSQL.Destroy;
begin
inherited;
end;
function TServiceRemoteSQL.Execute(const aSQL: RawUTF8; aExpectResults,
aExpanded: Boolean): RawJSON;
var
res: ISQLDBRows;
begin
if Props=nil then
raise Exception.Create('Connect call required before Execute');
res := Props.ExecuteInlined(aSQL,aExpectResults);
if res = nil then
result := ''
else
result := res.FetchAllAsJSON(aExpanded);
end;
Client Side
property Service: IRemoteSQL read GetService write FService;
procedure TfrmAssetProperty.LoadAssetProperties;
var
lSQLTable: TSQLTable;
sSQL: string;
lDataSet : TDataSet;
begin
if cxGridDBTableProp.DataController.DataSource = nil then
cxGridDBTableProp.DataController.DataSource := TDataSource.Create(Self);
sSQL := 'select a.id, a.Kode, a.nama, a.DefaultValue, a.Description , b.kode as UOM ' +
' from AssetProperty a' +
' LEFT JOIN UOM b on a.UOM = b.id ' +
' ORDER BY a.Nama';
lDataSet := JSONToDataSet(Self,Service.Execute(sSQL,True, True));
cxGridDBTableProp.DataController.DataSource.DataSet := lDataSet;
end;
Don't forget to register the service in server and client. Thank You.
Hi AOG, I execute SQL in SQL Server management Studio. It's executed well.
I use SQL Server as my database. I executed the SQL and it's executed well.
Thank You
I have 2 models :
TUOM = class(TSQLRecord)
private
FKode: RawUTF8;
FNama: RawUTF8;
protected
published
property Kode: RawUTF8 index 10 read FKode write FKode;
property Nama: RawUTF8 read FNama write FNama;
end;
TAssetProperty = class(TSQLRecord)
private
FDefaultValue: RawUTF8;
FDescription: RawUTF8;
FKode: RawUTF8;
FNama: RawUTF8;
FUOM: TUOM;
protected
public
published
property DefaultValue: RawUTF8 read FDefaultValue write FDefaultValue;
property Description: RawUTF8 read FDescription write FDescription;
property Kode: RawUTF8 index 10 read FKode write FKode;
property Nama: RawUTF8 read FNama write FNama;
property UOM: TUOM read FUOM write FUOM;
end;
I want to display TAssetProperty into DBGrid, here is my code :
sSQL := 'select Kode, nama, DefaultValue, Description, uom from AssetProperty' ;
if cxGridDBTableProp.DataController.DataSource = nil then
cxGridDBTableProp.DataController.DataSource := TDataSource.Create(Self);
lSQLTable := Client.ExecuteList([], sSQL);
cxGridDBTableProp.DataController.DataSource.DataSet := TSynSQLTableDataSet.Create(Self, lSQLTable);
cxGridDBTableProp.DataController.CreateAllItems(True);
with above code, it displays all data TAssetProperty but Field UOM will display UOM.ID. I want to display UOM.Kode. Then i change the code :
//sSQL := 'select Kode, nama, DefaultValue, Description, uom from AssetProperty' ;
sSQL := 'select a.Kode, a.nama, a.DefaultValue, a.Description , b.kode as UOM ' +
' from AssetProperty a' +
' LEFT JOIN UOM b on a.UOM = b.id ';
' ORDER BY a.Nama';
with the above code I get Access Violation. Could you give a solution to get what i want ?
Thank You
Pages: 1