Oracle LRS: Linear Referencing in Oracle - oracle

Does anybody know how to do Linear Referencing in Oracle?
I have a table with my route geometries, like
id routename geometry
-- --------- ----------
1 Mainstreet SDO_GEOMETRY
2 5th Avenue SDO_GEOMETRY
and I have a table with my events, like
id routename velocity from to
-- --------- -------- ---- ----
1 Mainstreet 75mph 0.0 52.5
2 Mainstreet 45mph 52.5 102.0
3 5th Avenue 75mph 0.0 78.0
I want to get the events as standard SDO_GEOMETRIES, like:
id routename velocity geometry
-- --------- -------- --------
1 Mainstreet 75mph SDO_GEOMETRY
2 Mainstreet 45mph SDO_GEOMETRY
3 5th Avenue 75mph SDO_GEOMETRY
In ArcGis or Geomedia it is very simple to achieve that... must be possible in Oracle I guess?

Related

When to add a sequence of fields in a materialized view

Good evening,
I am trying to understand in which cases the sequence would be used, for the example below, since the rowids would not always give me a single row to manage the changes.
Why consider a sequence of additional fields?
I will be grateful if you could clarify the doubt, with some example.
Thank you so much,
Greetings.
CREATE MATERIALIZED VIEW LOG ON sales
WITH ROWID, SEQUENCE(amount_sold, time_id, prod_id)
INCLUDING NEW VALUES;
Now imagine that you want to create a materialized view that contains aggregates on this table. Because the materialized view log has been created with all referenced columns in the materialized view's defining query, the materialized view is fast refreshable. If DML is applied against the sales table, then the changes are reflected in the materialized view when the commit is issued.
CREATE MATERIALIZED VIEW sum_sales
REFRESH FAST ON COMMIT AS
SELECT s.time_id, COUNT(*) AS count_grp,
SUM(s.amount_sold) AS sum_dollar_sales,
COUNT(s.amount_sold) AS count_dollar_sales
FROM sales s
GROUP BY s.time_id;
Without using the sequence, you will have the following error
ORA-12033: cannot use filter columns from materialized view log on "ADMIN"."SALES"
So let me try to explain why, by using a Testcase
drop table sales;
create table sales (time_id number, prod_id number, amount_sold number)
CREATE MATERIALIZED VIEW LOG ON sales
WITH ROWID, SEQUENCE(amount_sold, time_id, prod_id)
INCLUDING NEW VALUES;
truncate table sales;
insert into sales values (1,1,23);
insert into sales values (1,2,23);
commit;
select time_id, sum(amount_sold) from sales group by time_id;
TIME_ID SUM(AMOUNT_SOLD)
------- ----------------
1 46
Now Imagine, that you will modify a row multiple times.
update sales set amount_sold = 55 where time_id = 1 and PROD_ID = 1;
update sales set amount_sold = 12 where time_id = 1 and PROD_ID = 1;
select time_id, sum(amount_sold) from sales group by time_id;
TIME_ID SUM(AMOUNT_SOLD)
------- ----------------
1 35
your new amount_sold is 35. How to do a fast refresh without reading the value for the row (1,2) because you only modified (1,1)
select * from MLOG$_SALES where DMLTYPE$$ != 'I' order by ;
AMOUNT_SOLD TIME_ID PROD_ID M_ROW$$ SEQUENCE$$ SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$
----------- ------- ------- ------------------ ---------- -------------------- --------- --------- --------------- ----------------
23 1 1 AAAwaSAAAAAAFpTAAA 105 4000-01-01T00:00:00Z U U CA== 4222223434942993
55 1 1 AAAwaSAAAAAAFpTAAA 106 4000-01-01T00:00:00Z U N CA== 4222223434942993
55 1 1 AAAwaSAAAAAAFpTAAA 107 4000-01-01T00:00:00Z U U CA== 4222223434942993
12 1 1 AAAwaSAAAAAAFpTAAA 108 4000-01-01T00:00:00Z U N CA== 4222223434942993
So you can use the previous value 46 and increment/decrement using the old/new value as follow
select 46 - 23 + 55 - 55 + 12 as newval from dual;
NEWVAL
------
35
You can also do the same when doing a delete
This is not possible having only the rowid. To generate the new value 35 you need to read an unmodified value, so you cannot do a fast refresh.
Hope that this can help you to understand in which cases the sequence is used

Access other values ​in a trigger before save Oracle

Is it possible to access the previous values ​​that have not yet been stored in the database?
I have a table related to a particular module (MOD) which I will call table XA.
I can insert multiple records into XA simultaneously they are going to be inserted, I cannot change this fact.
For example, the following data is inserted in XA
ID | ParentId | Type | Name | Value
1 | 1 | 5 | Cost | 20000
2 | 1 | 9 | Risk | 10000
And I need in this case to insert / update a record in this same table. A calculated value
At the moment of executing the trigger, the value with the name of Cost for example is inserted first, and then the value of Risk.
When evaluating the Risk, I must have the ability to know what the Cost value is to make the calculation and insert the calculated record.
I tried to create a Package to which I would feed the data, but I still have the same problem.
create or replace PACKAGE GLOBAL
IS
PRAGMA SERIALLY_REUSABLE;
TYPE arr IS TABLE OF VARCHAR2 (32)
INDEX BY VARCHAR2 (50);
NUMB arr;
END GLOBAL;
//Using in trigger
GLOBAL.NUMB (:NEW.ID || '-' || :NEW.ParentId) := :NEW.Value;
BEGIN
IF :NEW.Type == 9 AND GLOBAL.NUMB (5 || '-' || :NEW.ParentId) IS NOT NULL
THEN
// calculate and insert record
ELSE IF :NEW.Type == 5 AND GLOBAL.NUMB (9 || '-' || :NEW.ParentId) IS NOT NULL
// calculate and insert record
END IF;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
// NOT HAVE TWO INSERT TO SAME REGISTER
END;
Values ​​5 and 9 are for reference.
Both records are not always inserted, one or more can be inserted, even the calculated value can be imputed but must be replaced by the calculation.
And I can't create a view since there is an internal process that depends on this particular table.
Do you really really must store calculated value into a table? That's usually not the best idea as you have to maintain it in any possible case (inserts, updates, deletes).
Therefore, another suggestion: a view. Here's an example; my "calculation" is simple, I'm just subtracting cost - risk as I don't know what you really do. If calculation is very complex and should be run every time on a very large data set, yes - performance might suffer.
Anyway, here you go; see if it helps.
Sample data:
SQL> select * From xa order by parentid, name;
ID PARENTID TYPE NAME VALUE
---------- ---------- ---------- ---- ----------
1 1 5 Cost 20000
2 1 9 Risk 10000
5 4 5 Cost 4000
7 4 9 Risk 800
A view:
SQL> create or replace view v_xa as
2 select id,
3 parentid,
4 type,
5 name,
6 value
7 from xa
8 union all
9 select 0 id,
10 parentid,
11 99 type,
12 'Calc' name,
13 sum(case when type = 5 then value
14 when type = 9 then -value
15 end) value
16 from xa
17 group by parentid;
View created.
What does it contain?
SQL> select * from v_xa
2 order by parentid, type;
ID PARENTID TYPE NAME VALUE
---------- ---------- ---------- ---- ----------
1 1 5 Cost 20000
2 1 9 Risk 10000
0 1 99 Calc 10000
5 4 5 Cost 4000
7 4 9 Risk 800
0 4 99 Calc 3200
6 rows selected.
SQL>

select query in oracle

I have database design like this...
dated ref weight no. address
21-03-2013 ABCD/EDFG 1234 A45 A1
20-03-2013 ABCD/EDFG 789 A56 A2
25-03-2013 ABCD/EDFG 6981 A99 A5
23-03-2013 GAJHS/ASDH 72 A82 GV
what i want here in the query result is something like this....
search on the basis of no.
but then, it has to see if the ref of that row exists more times and if it exists then it has to add the weight of all such rows keeping in mind dated of all such records should be less than the dated of selected no..
example -
no. = A56
three rows exist with same ref(ABCD/EDFG)
but dated of A56 is lower among all so results should be
ref ------ weight -------- no. -------- address
ABCD/EDFG ------ 789 ----------- A56 -------- A2
but in the case of no. = A99 results should be like this -
ref ----------- weight -------- no. -------- address
ABCD/EDFG --- (789+6981+1234) ----------- A99 -------- A5
as dated of A99 is greater than other two records.
please help me in this query.
select
ref,
sum(weight) over (partition by ref order by dated) as weight,
no,
address
from
...

kettle / auto-referencing table

I have an excel sheet with poeple, each people has a father and a mother that is in the same poeple sheet. My exel table looks like that :
poeple --- father --- mother
john -------- tony ----- jane
tony -------- jack
I would like to import the datas to an Oracle database table that look like :
id --- poeple --- father --- mother
0 -----jack
1 -----tony-------- 0
2 -----jane
what should be my workflow ?
3 ----john -------- 1-----------2
It would be easier to at least start by loading the data into a table with the surrogate ID:
people father mother
------ ------ ------
john tony jane
tony jack
Then you can add rows for the fathers and mothers not already in the "people" column:
insert into mytable (people)
( select mother from mytable
union
select father from mytable
)
minus
select people from mytable;
That will give you:
people father mother
------ ------ ------
jack
tony jack
jane
john tony jane
You can then add a surrogate ID for each row and use that instead, if you need it.

Is there a name for this representation of data?

Suppose you have data for which a normalized view would be something like
ID First Name Last Name Height
-- ---------- --------- ------
1 Ann Jones 63
2 John Smith 72
But the data comes to us in this representation:
ID Type Value
-- ---- -----
1 'FirstName' Ann
1 'LastName' Jones
1 'Height' 63
2 'FirstName' John
2 'LastName' Smith
2 'Height' 72
It's sort of a normalized table turned sideways, or an "unpivoted" table.
My question is: is there a NAME for this kind of representation -- these 'ID, Type, Value' triples? (In reality the Type is an integer and maps to a type table, but I made it a string to make it clearer what it represented.)
I suppose this could be considered as close to the EAV (Entity-Attribute-Value) Model
Except you only have the two following tables :
Entity
Value
And no Attribute table.

Resources