Updating joined queries with ADO - delphi

I have a select query that joins 3 tables to display information. If I want to update a field is do
ADOQuery.Edit.
<Set fields Values>
ADOQuery.Post.
I get the following error howwever 'Insufficient key column information for updating or refresing' and I'm not sure how to proceed.
Thank you.
Pieter

Try this OnCreate:
YourADODataSet.Properties['Unique Table'].Value := 'YourTable';
This will let the Engine send only one (instead of two) query from joined tables.

Related

Using FireDac to update only 1 of a duplicate row (no primary key or unique field)

I have an old application I am supporting that uses a Microsoft Access database. The original table design did not add primary keys to every table. I am working on a migration program that among other things is adding and filling in a new primary key field (GUID) when needed.
This is happening in three steps:
Add a new guid field with no constraints
Fill the field with new unique guids
Add the primary key constraints
My problem is setting the unique guids when the table has duplicate rows. Here is my code to set the guids.
Query.SQL.Add('SELECT * FROM ' + TableName);
Query.Open;
while Query.Eof = false do
begin
Query.Edit;
Query.FieldByName(NewPrimaryKeyFieldName).AsGuid := TGuid.NewGuid;
Query.Post;
Query.Next;
end;
FireDac generates an update statement that contains a where clause with all the original fields/values in the row (since there is no unique field for it to use). However, because the rows are complete duplicates the statement still updates two rows.
FireDac correctly errors with this message
Update command updated [2] instead of [1] record.
I can open up the database in Access and delete the duplicate records or assign them a unique guid by editing the table. I would like my conversion tool to automatically do this.
Is there some way to work with these duplicate rows in FireDac? Either to update just one at a time, or to delete just one of them?
In my opinion there is no way to do it with just one SQL Statement.
I would do this:
1. Copy the whole table without duplicates by using a new temp table
SELECT DISTINCT * FROM <TABLENAME>
Add the Keys
Delete old table content and copy new content from new table
Notes:
The DB Should be unavailable for everyone else for that Operation
2. Make BACKUP before

Select join table fields in SOLR

I have a SQL query something like this
SELECT
P . ID,
P .code,
l.parent_id
FROM
properties P
LEFT JOIN locations l ON l. ID = P .location_id;
I want to convert this query to SOLR query. I can join two cores by below system
http://example.com:8999/solr/properties/select?q=*:*&fq={!join from=id to=location_id fromIndex=locations}p_id:12345
But I cant select the fields of locations core.How can I do this? Your valuable suggestion will be appreciated.
You can use subquery in the fl. Something like this fl=*,locations:[subquery fromIndex=locations]&locations.q={!terms f=id v=$row.location_id}
More info here https://lucene.apache.org/solr/guide/6_6/transforming-result-documents.html#TransformingResultDocuments-subquery
You can't. Solr does not support returning fields from both ends of an join. Solr is not a relational database, so you're usually better off trying to not use it as one.
Instead, index the information about each location to each property, and query based on that.
If any location info changes (which it turns out, usually happens very rarely), reindex the documents assigned that location.

The query is not working?

In my application I use sqlite as a Backing store.For my use I create Two tables for Surgeon and Schedule with surgeon having columns Name(VARCHAR),id(int) and Schedule having id(int),Surgeon(int),Values(VARCHAR).
The Surgeon column in Schedule table is pointing to the id column in Surgeon table. I use The Below query to select values from the Schedule table for the Surgeon with id=1
SELECT Schedule.Values,Name from Schedule,Surgeon where Schedule.Surgeon==Surgeon.id and Surgeon.id=2
But I got error as below
SQLiteManager: Likely SQL syntax error: SELECT Schedule.Values,Name from Schedule,Surgeon where Schedule.Surgeon==Surgeon.id and Surgeon.id=2 [ near "Values": syntax error ]
I don't know where it went wrong, I have't used the database before so forgive me if the question is much basic
You have named one of the columns in Schedule  as values Change it to something else that is not a key word for sqlite. you should not use key string to name the column  First you have to take a look at the keys in sqlite
If u want to take the Name, then try Surgeon.Name

DBExpress: How to find a primary key field?

I have a TSimpleDataSet based on dinamically created SQL query. I need to know which field is a primary key?
SimpleDataSet1.DataSet.SetSchemaInfo(stIndexes, 'myTable' ,'');
This code tells me that i have a primary key with name 'someName', but how can i know which field (column) works with this index?
A Primary Key/Index can belong to several columns (not just one).
The schema stIndexes dataset will return the PK name INDEX_NAME and the columns that construct that PK/Index (COLUMN_NAME). INDEX_TYPE will tell you which index types you have (eSQLNonUnique/eSQLUnique/eSQLPrimaryKey).
I have never worked with TSimpleDataSet but check if the indexes information is stored in
IndexDefs[TIndexDef].Name/Fields/Options - if ixPrimary in Options then this is your PK. and Fields belongs to that index.
Take a look at the source at SqlExpr.pas: TCustomSQLDataSet.AddIndexDefs.
Note how TCustomSQLDataSet returns the TableName (and then the indexs information) from the command text:
...
if FCommandType = ctTable then
TableName := FCommandText
else
TableName := GetTableNameFromSQL(CommandText);
DataSet := FSQLConnection.OpenSchemaTable(stIndexes, TableName, '', '', '');
...
I think the simple data set does not provide that information.
However, i am sure there are components for that. Check, for Oracle database, Devart's ODAC.
Basically, it involves only one query to the database.
However, it is not something that components will offer by default as, because it involves a different query, it leads to slow response times.
For Oracle database, query on user_indexes.

Firebird Insert Distinct Data Using ZeosLib and Delphi

I'm using Zeos 7, and Delphi 2009 and want to check to see if a value is already in the database under a specific field before I post the data to the database.
Example: Field Keyword
Values of Cheese, Mouse, Trap
tblkeywordKEYWORD.Value = Cheese
What is wrong with the following? And is there a better way?
zQueryKeyword.SQL.Add('IF NOT EXISTS(Select KEYWORD from KEYWORDLIST ='''+
tblkeywordKEYWORD.Value+''')INSERT into KEYWORDLIST(KEYWORD) VALUES ('''+
tblkeywordKEYWORD.Value+'''))');
zQueryKeyword.ExecSql;
I tried using the unique constraint in IBExpert, but it gives the following error:
Invalid insert or update value(s): object columns are
constrained - no 2 table rows can have duplicate column values.
attempt to store duplicate value (visible to active transactions) in unique index "UNQ1_KEYWORDLIST".
Consider to use UPDATE OR INSERT or MERGE statements:
update or insert into KEYWORDLIST (KEYWORD) values(:KEYWORD) matching(KEYWORD)
For details check the following documents in your Firebird installation folder:
doc\sql.extensions\README.update_or_insert.txt
doc\sql.extensions\README.merge.txt

Resources