Posted By: michaelbell How to update SDO_GEOMETRY column - 02/02/04 09:46 PM
We're trying to update a table, that contains a column 'SHAPE' of type 'SDO_GEOMETRY', but that far with no success.

Could you please point me to an example of how to update an object column? All examples I found refer to typed tables and not a single object column.
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/02/04 10:28 PM
What is your Direct Oracle Access version?
Posted By: michaelbell Re: How to update SDO_GEOMETRY column - 02/03/04 03:07 PM
Delphi 7, DOA 4.0.3 trial version with Oracle 9.2

Just wanted to know if there is an example in your documentation. (Not using typed tables...)
If not, I would be pleased if you could post a few lines to show me how do do it.
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/03/04 10:47 PM
I checked out the SDO_GEOMETRY type and noticed that it contains a VARRAY, which cannot be updated through the TOracleDataSet. Therefore you would need a TOracleQuery and TOracleObject to update this record. I don't have an example that uses the SDO_GEOMERTY type, but the documentation contains various examples for nested objects an collections.
Posted By: michaelbell Re: How to update SDO_GEOMETRY column - 02/03/04 11:16 PM
I found some examples, but as I said they all refer to typed tables.
If I look at TOracleObject.Create I have to give a tablename as third parameter to make the object persistent. But I don't have a table, I only have a _column_.

Let's say I have a table with three columns:
ID number
SomeText varchar2(100)
SHAPE SDO_GEOMETRY

How can I create an updatable TOracleObject instance for the value in the "SHAPE" column?
Posted By: al0 Re: How to update SDO_GEOMETRY column - 02/04/04 02:39 AM
[quote]Originally posted by Marco Kalter:
I checked out the SDO_GEOMETRY type and noticed that it contains a VARRAY, which cannot be updated through the TOracleDataSet. [/quote]Are there any plans to make collection type columns updatable through dataset (or nested dataset) in future releases of DOA?
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/04/04 10:48 PM
Nested tables are updateable. Varrays are currently read-only. This will be addressed in a future release.
Posted By: michaelbell Re: How to update SDO_GEOMETRY column - 02/05/04 08:41 PM
Please, back to the topic.
I never said I wanted to update through a TOracleDataset. Using TOracleQuery with variables or a TOracleObject instance would be fine.

Meanwhile I learned the following:
"REF cannot operate on column objects or otherwise nested objects, because such objects do not have an OID." [PL/SQL Programming, Steven Feuerstein]

So, object columns do not have a reference pointer. Thus, they are not so called "persistant objects"
Could that be the problem, that I can't write into a TOracleObject instance?

How about an example on using TOracleQuery and variables to update an object column? Still couldn't find one in your documentation.
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/06/04 09:01 PM
The object is indeed not persistent, so you will have to query or create a TOracleObject of a SDO_GEOMETRY type, manipulate its attributes, and execute an update or insert that uses an object variable that is associated with this TOracleObject instance.

I will create a complete SDO_GEOMETRY example and post it here shortly.
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/09/04 10:45 PM
The procedure below is an example how to insert, select and update an sdo_geometry column in a table.
The demo uses a transient object instead of pure SQL to access the attributes and collections.
All components are created at runtime instead of designtime for demo purposes.
Code
procedure SDOGeometryDemo;
var Session: TOracleSession;
    Query: TOracleQuery;
    Polygon, ElemInfo, Ordinates: TOracleObject;
begin
  // Create a session and logon as scott
  Session := TOracleSession.Create(nil);
  Session.LogonUsername := 'scott';
  Session.LogonPassword := 'tiger';
  Session.LogOn;
  // Create a query to create/access/drop table
  Query := TOracleQuery.Create(nil);
  Query.Session := Session;
  with Query do
  begin
    // Create the table
    SQL.Text := 'create table cola_markets(mkt_id number, name varchar2(32), shape mdsys.sdo_geometry)';
    Execute;
    // Create a transient SDO_GEOMETRY object instance
    Polygon := TOracleObject.Create(Session, 'mdsys.sdo_geometry', '');
    // Set the type to a 2 dimensional polygon
    Polygon.SetAttr('sdo_gtype', 2001);
    // Define a rectangle
    ElemInfo := Polygon.ObjAttr('sdo_elem_info');
    ElemInfo.Elements[0] := 1;
    ElemInfo.Elements[1] := 1003;
    ElemInfo.Elements[2] := 3;
    // Set 2 points at 1,1 and 5,7
    Ordinates := Polygon.ObjAttr('sdo_ordinates');
    Ordinates.Elements[0] := 1;
    Ordinates.Elements[1] := 1;
    Ordinates.Elements[2] := 5;
    Ordinates.Elements[3] := 7;
    // Insert a record with this object instance
    SQL.Text := 'insert into cola_markets(mkt_id, name, shape) values (1, ''cola_a'', :polygon)';
    DeclareVariable('polygon', otObject);
    SetComplexVariable('polygon', Polygon);
    Execute;
    Session.Commit;
    // Free the object
    Polygon.Free;
    // Requery the row with the previously inserted object instance
    Clear;
    SQL.Text := 'select * from cola_markets where mkt_id = 1';
    Execute;
    if not Eof then
    begin
      // Create a copy of the queried instance
      Polygon := TOracleObject.Create(Session, 'mdsys.sdo_geometry', '');
      Polygon.Assign(ObjField('shape'));
      // Change the 2nd point from 5,7 to 6,8
      Polygon.ObjAttr('sdo_ordinates').Elements[2] := 6;
      Polygon.ObjAttr('sdo_ordinates').Elements[3] := 8;
      // Update the record with this modified object instance
      Clear;
      SQL.Text := 'update cola_markets set shape = :polygon where mkt_id = 1';
      DeclareVariable('polygon', otObject);
      SetComplexVariable('polygon', Polygon);
      Execute;
      Session.Commit;
      // Free the object
      Polygon.Free;
    end;
    // Drop the table
    Clear;
    SQL.Text := 'drop table cola_markets';
    Execute;
  end;
  // Free the query and session
  Query.Free;
  Session.Free;
end;
Posted By: michaelbell Re: How to update SDO_GEOMETRY column - 02/10/04 01:46 PM
That was exactly the example I wanted. Many, many thanks!!
There seems nothing left, you can't do with DOA... laugh
Posted By: al0 Re: How to update SDO_GEOMETRY column - 02/10/04 03:30 PM
[quote]Originally posted by Marco Kalter:
Nested tables are updateable. Varrays are currently read-only. This will be addressed in a future release. [/quote]With TOracleQuery, yes. But my question was concerning the TOracleataset. If I put in the sql
statement that selects nested tables/varray columns they even not appears in Fields (or FieldDefs) properties of dataset!
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/10/04 10:59 PM
[quote]Originally posted by al0:
With TOracleQuery, yes. But my question was concerning the TOracleataset. If I put in the sql statement that selects nested tables/varray columns they even not appears in Fields (or FieldDefs) properties of dataset! [/quote]That is correct. However, if you add a detail dataset and select the dataset with the collection attributes or columns as the master, the detail dataset will be populated with the collection records.
Posted By: al0 Re: How to update SDO_GEOMETRY column - 02/11/04 03:40 AM
[quote]Originally posted by Marco Kalter:
[QUOTE]Originally posted by al0:
[qb] However, if you add a detail dataset and select the dataset with the collection attributes or columns as the master, the detail dataset will be populated with the collection records.
[/quote]How I can find at runtime which collections I have in master dataset? How can I specify for detail dataset which of collection from master datase shall it represent?

The code used at design time in OracleData.pas is, in essence, incorrect shocked (at least as far as I can undestand it), as it provides not the collections present in SELECT but collections from "updating table" of that select. So it may propose some unselected columns and will not propose some explicitly selected columns (yes, later are not updatable but anyway user want to see them).

And it seems that one more issue exists frown - collection are selected by the internal TOracleQuery of Master dataset completely unavailable from outside frown and then reselected by detail dataset. so they are selected twice effectively wasting the memory and execution time (especially for big collections).

Shortly, it doesn't deals with selected collections, it tries to re-select it with his own SQL. It more or less Ok from collections that come from the tables, but collection may appears to select in many other ways - e.g. as resul of function calls, direct creation in the select list (select TABLE(MyNumberCollection(1,2,3,4,5)) from dual) etc. So to hanle collection (at least in read-only mode) via TDataset are need or collection-type field in TOracleDataSet or special dataset descendant like TCollectionWrapperDataset. confused
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/11/04 11:08 PM
For performance purposes you can omit the collection field(s) from the select statement of the master dataset. It is not needed.

If you check the SQL text of the detail dataset, you will notice that it is a select statement on the collection that references the primary key of the master dataset. This is really all that is required.
Posted By: al0 Re: How to update SDO_GEOMETRY column - 02/12/04 05:05 AM
[quote]Originally posted by Marco Kalter:
For performance purposes you can omit the collection field(s) from the select statement of the master dataset. It is not needed.

If you check the SQL text of the detail dataset, you will notice that it is a select statement on the collection that references the primary key of the master dataset. This is really all that is required.
[/quote]What to do if master dataset has no primary key?
What to do i collections comes not from "updating table" of the query?
What to do if collection is not taken from the table but is caulculated by function ?

Is it any chance to see (read-only) such collection throgh dataset? BTW I have taken short look on trial version on ODAc - it does it easily.
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/12/04 10:25 PM
You can access any collection, as long as you can think of a select statement to fetch its records.
Posted By: al0 Re: How to update SDO_GEOMETRY column - 02/13/04 01:38 AM
[quote]Originally posted by Marco Kalter:
You can access any collection, as long as you can think of a select statement to fetch its records. [/quote]I repeat once more - yes, with TOraQuery I can.

The question was abour TOracleDataset - if I put in run-time in its the select property the select that contains collection in the select list the fields property contains no fields for those collection. E.g. if I have
Code
select MyNumber,MyCollection,MyChar from MyView
the fields property of the dataset contains only 2 filds - Fields[0] represents MyNumber and Fields[1] represents MyChar. MyCollection is skipped over. I ever is unable to determine that this select returns some collections (if I don't know it in advance.

Probably I don't understand something eek then point me out how to deal with TOracleDataset and collections in run-time, with sample code if possible.

So I need the following:
  • assign to SQL property of TOracleDataSET some SELECT statement
  • Execute select
  • Check the results of select and find if any collections are among results
  • Present this collection to the user, desirable in data-aware grids

I wish to note that nor the select statement nor types in collections are known in advance.

Thank you in advance.
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 02/13/04 10:19 PM
I will post an example shortly that will clarify this.
Posted By: al0 Re: How to update SDO_GEOMETRY column - 02/14/04 01:15 AM
[quote]Originally posted by Marco Kalter:
I will post an example shortly that will clarify this. [/quote]Thanks. Wait impatiently. :rolleyes:
Posted By: al0 Re: How to update SDO_GEOMETRY column - 03/01/04 02:48 AM
[quote]Originally posted by Marco Kalter:
I will post an example shortly that will clarify this. [/quote]Might I remeber about that example?
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 03/01/04 10:48 PM
Oops, sorry, I forgot. I will get round to this shortly.
Posted By: al0 Re: How to update SDO_GEOMETRY column - 03/02/04 03:11 AM
[quote]Originally posted by Marco Kalter:
Oops, sorry, I forgot. I will get round to this shortly. [/quote]Thanks.
I sincerely hope for it.
Posted By: Marco Kalter Re: How to update SDO_GEOMETRY column - 03/04/04 06:31 PM
The standard TOracleDataSet functionality for collections is based on a master/detail relation. The table of the master dataset contains one or more collection columns or attributes, that do not necessarily have to be included in the query (for efficiency reasons they can be omitted). The collection can be displayed in a detail dataset that contains a query for a collection column or attribute of the current master record. Lets assume a ROOMS table that contains a RESERVATIONS nested table column. The detail dataset query will be something like this:
Code
select * from table(select m.reservations 
                    from rooms m 
                    where m.room_number = :room_number)
The key query is the single record subselect that returns the collection:
Code
select m.reservations 
from rooms m 
where m.room_number = :room_number
This is the query that returns a single collection column for a single record. If you want to view a collection in a dataset, you must create such a query at design-time or at run-time. It doesn't have to be a master/detail setup either. Let's assume you have presented the user with a selection of rooms, and the user wants to view the reservations for room '13b'. All you need to do is present the result set of the following query:
Code
select * from table(select m.reservations 
                    from rooms m 
                    where m.room_number = '13b')
Or, to make it updateable:
Code
select t.*, rowid from table(select m.reservations 
                             from rooms m 
                             where m.room_number = '13b') t
As you can see, there is no master/detail setup necessary. All that is required is that you know the query that returns the collection you want to view or edit.

I hope this helps.
Posted By: al0 Re: How to update SDO_GEOMETRY column - 03/04/04 08:58 PM
[quote]Originally posted by Marco Kalter:
All that is required is that you know the query that returns the collection you want to view or edit.

I hope this helps.
[/quote]I have written in my post that asked for sample code
[quote]
I wish to note that nor the select statement nor types in collections are known in advance.
[/quote]So your sample is of no use for me, sorry.
I have absolutely no control over selects - I have do the following:

  • obtain select from outside
  • execute it
  • check if any collections are present
  • show collections from current records in data-aware controls


It quite possible that collections just can not be obtained with separate selects (they may be results of function calls in the select list and so on).

I have to mention that I have tried this with trial version of ODAC - it is piece of cake.
© Allround Automations forums