UUID - Unique Field
Posted: Fri May 17, 2019 11:52 am
There was something I failed to address at our gathering this month.
The issue came up when Bobby Drakos was trying to update a record in a SQL cursor.
The cursor was not an updateable cursor because the filtering system used the LIKE() scalar function.
So when the application tried to update the record with DC_DbGather() it could not acquire a Lock on the record.
A workaround for this is to make sure that DC_DbGather() uses a SQL UPDATE statement to update the record.
Therefore I am writing a new function named DC_DbRecord2SqlUpdate() which will be called by DC_DbGather() in the event that SQL is needed to update the record.
There are a few caveats which must be addressed, however.
The SQL UPDATE command must use a WHERE clause to insure that the correct record gets updated.
To narrow down an update to a single record, it must know the name of a field that has a value which is UNIQUE to the entire table.
For example, the unique number in a Drivers database would be the HACK.
Therefore the function would be called like this:
cStatement := DC_DbRecord2Update( oRecord, ‘MN_DRV’, ‘HACK’)
That statement would be executed via an SQL Execute function.
In SqlQuery.exe, however, this is a much bigger problem because I have no way of knowing which field is unique when doing an update.
Also, there are many tables in which there is NO unique field.
SQL updates REQUIRE a UNIQUE field, therefore you should all be preparing for this reality, even if you don’t anticipate using SQL UPDATE any time soon.
This is very simple.
Just add a field named UUID,’C’,36,0 to every table.
Every time you add a new record to the table, replace that field with the following code:
REPLACE UUID WITH uuidtochar(uuidcreate()) // example: b8b9f770-991f-4afb-aa65-6751acbcef25
If you use DC_DbGather() to add new records, I will automatically add the unique ID to the UUID field (if it exists).
This will make updates much easier going forward.
I will also be adding a new parameter to DC_DbGather() - <oSession>.
This will be a pointer to a DacSession() object to be used for the SQL UPDATE in the event that a record lock cannot be obtained.
I will also be creating a new class named DC_DacSession(). It will inherit from DacSession() but will contain some new iVars to make SQL work simpler.
For example, there will be an iVar to store a code block which will be called to execute any SQL statements.
This way, when you make a DacSession connection to your ADS or ODBC data, you can also define which SQL execute function to use.
To make it easier for you to add the UUID field to your tables, I will be adding a new feature to SqlQuery in the next update that will do this for you for all tables in a selected connection.
The issue came up when Bobby Drakos was trying to update a record in a SQL cursor.
The cursor was not an updateable cursor because the filtering system used the LIKE() scalar function.
So when the application tried to update the record with DC_DbGather() it could not acquire a Lock on the record.
A workaround for this is to make sure that DC_DbGather() uses a SQL UPDATE statement to update the record.
Therefore I am writing a new function named DC_DbRecord2SqlUpdate() which will be called by DC_DbGather() in the event that SQL is needed to update the record.
There are a few caveats which must be addressed, however.
The SQL UPDATE command must use a WHERE clause to insure that the correct record gets updated.
To narrow down an update to a single record, it must know the name of a field that has a value which is UNIQUE to the entire table.
For example, the unique number in a Drivers database would be the HACK.
Therefore the function would be called like this:
cStatement := DC_DbRecord2Update( oRecord, ‘MN_DRV’, ‘HACK’)
That statement would be executed via an SQL Execute function.
In SqlQuery.exe, however, this is a much bigger problem because I have no way of knowing which field is unique when doing an update.
Also, there are many tables in which there is NO unique field.
SQL updates REQUIRE a UNIQUE field, therefore you should all be preparing for this reality, even if you don’t anticipate using SQL UPDATE any time soon.
This is very simple.
Just add a field named UUID,’C’,36,0 to every table.
Every time you add a new record to the table, replace that field with the following code:
REPLACE UUID WITH uuidtochar(uuidcreate()) // example: b8b9f770-991f-4afb-aa65-6751acbcef25
If you use DC_DbGather() to add new records, I will automatically add the unique ID to the UUID field (if it exists).
This will make updates much easier going forward.
I will also be adding a new parameter to DC_DbGather() - <oSession>.
This will be a pointer to a DacSession() object to be used for the SQL UPDATE in the event that a record lock cannot be obtained.
I will also be creating a new class named DC_DacSession(). It will inherit from DacSession() but will contain some new iVars to make SQL work simpler.
For example, there will be an iVar to store a code block which will be called to execute any SQL statements.
This way, when you make a DacSession connection to your ADS or ODBC data, you can also define which SQL execute function to use.
To make it easier for you to add the UUID field to your tables, I will be adding a new feature to SqlQuery in the next update that will do this for you for all tables in a selected connection.