Skip to Main Content

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, kasturi.

Asked: June 15, 2016 - 12:23 pm UTC

Last updated: June 18, 2016 - 1:11 am UTC

Version: 12c

Viewed 1000+ times

You Asked

Hello,

I need info that, is there any operator newly introduced for comparison of data(within a table for same column). i have following requirement:

I am having table as follow.
synonym_name table_name
A A_A
B B_A
C C_A
D D_A

synonym cane point either _A table or _B table. at a given point of time, i have logical family of tables defined above. this family should point to same set of table (i.e. either _A or _B).
i want to define this logic to see if family is belonging to same table set.

if data like below is present it should give me error or any indication.
synonym_name table_name
A A_A
B B_A
C C_A
D D_B

thanks in advance.

and Chris said...

So... there should only be one suffix in the column table_name?

i.e. you should get an error when trying to add D_B?

You can do this. But it's complex. You need to:

- Create a materialized view with a query identifying invalid rows
- Ensure this MV is fast refreshable on commit
- Add a check constraint to the MV. This validates that the query returns no rows.

For example:

CREATE TABLE t
    (synonym_name varchar(1), table_name varchar(3))
;
create materialized view log on t 
  with rowid (table_name) including new values;
 
create materialized view mv
refresh fast on commit as 
  select count(*) c
  from   t t1
  join   t t2
  on     substr(t1.table_name, -1, 1) <> substr(t2.table_name, -1, 1);
 
alter table mv add constraint chk check (c = 0);
    
INSERT INTO t (synonym_name, table_name)
VALUES ('A', 'A_A');
INSERT INTO t (synonym_name, table_name)
VALUES ('B', 'B_A');
INSERT INTO t (synonym_name, table_name)
VALUES ('C', 'C_A');
commit;

INSERT INTO t (synonym_name, table_name)
VALUES ('D', 'D_B');
commit;

SQL Error: ORA-12008: error in materialized view refresh path
ORA-02290: check constraint (CHRIS.CHK) violated

select * from t;

S TABLE_NAME                   
- ------------------------------
A A_A                           
B B_A                           
C C_A


This is fiddly. In particular, writing your query so fast refresh on commit of the MV is possible can be hard. Oracle Database serializes the MV refresh too. This can be a problem if you have lots of concurrent DML.

We have a proposal to make this much easier. Support for assertions. This would enable you do to something like:

create assertion only_one_suffix as check (
 (select count(*) c
  from   t t1
  join   t t2
  on     substr(t1.table_name, -1, 1) <> substr(t2.table_name, -1, 1)
 ) = 0
);


And you're done!

But we need your support for this! If you'd like to see this in Oracle Database, vote for it at:

https://community.oracle.com/ideas/13028

Rating

  (10 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

About assertions

Ghassan, June 15, 2016 - 4:04 pm UTC

I do not think that such assertions are reliable within the database purposes and maintability at least regarding the performance and objects dependencies.
Think about it. Let say a big table that you plug in such assertion. You may claim that this would be the designer decision and responsibilities whether to create such assertion or not.. but I call this a rubish database afterwhile.
Unless I didn't understand or miss something about your suggestion . I will be thankful if you clarify it and give more links.
I really do appreciate as many your amazing job for the oracle community.
Chris Saxon
June 16, 2016 - 6:52 am UTC

Can you elaborate on what you mean ?

An assertion is a statement that defines correctness of data. Now, obviously we dont have assertions in the database yet, but that doesn't mean you dont *currently* have rules/policies that define how your data has to be - it's more a question of how they are currently implemented.

My experience is that there are currently three ways these rules are implemented by application developers:

1) they are not (everyone just prays and hopes that the data is ok)
2) they are implemented wrongly (because people dont manage the concurrency and other issues correctly)
3) they are implemented correctly.

Assertions will be a means for getting more people from (1) and (2) toward (3).

very good info

kasturi, June 16, 2016 - 6:03 am UTC


Followup

Ghassan, June 16, 2016 - 7:31 am UTC

Thank you for replying. I've just taking your above example. Assertion is here to cross rows checks . Keyword create means a db object creation. This create imply a relationship btw the object and the data. Data are instable and perpetual changing things. Within Assertions Your are hoping make closer relationship btw data and deep db objects concistancy. This lead to huge database internal changes eg inventing a new kind of rdbms. I do not believe that oracle corporation think that the suggestion is feasible at least for a near future and one thing at least as I said above is performance and data integrity.

For now my own opinion is that this suggestion cannot be implemented . That's my convinced feelings.
Connor McDonald
June 16, 2016 - 8:05 am UTC

We're suggesting assertions because we believe we can implement them!

Suggestion

Ghassan, June 16, 2016 - 8:44 am UTC

Good luck. If you have time suggest the mecanism of how and when the assertion checks fire when touwsands of insertions on huge table are going on while an assertion include a count (*) . If you have more time pls give the behavior of performance, stats and histog calc. .etc.

How would you deal with this requirement?

Toon Koppelaars, June 16, 2016 - 11:34 am UTC

I'll elaborate on SQL assertions, in a bit...

@Ghassan

> "I do not think that such assertions are reliable within the database purposes and maintainability at least regarding the performance and objects dependencies."

- Do you think the MV-approach is "reliable"?
- How would you deal with a data constraint that the OP introduced?


@toon

ghassan, June 16, 2016 - 12:49 pm UTC

hi toon and thanks for impliction.
i am waiting for the elaboration.

meanwhile comparing what is defined as assertion to the MV is like comparing tomato to banana
a MV is a physical structure like a table but have more or another apprehensions
what i understood from these asked assertions is that they are in some sides similar to a constraints but on the rows level ; means we are defining a new concept as like some software do regarding the way to parameter a business
it is not easy i know to explain this in some words on this post

an oracle constraint is on col side and affect a single row
so algebra logique is reliable on what we have as physical infrastructure currently
when we ask to implement a such assertion whom postability affect all rows of a table that is different approoch

i a not saying that implementation is difficult no it is very easy to do eg "create an assertion as ..."
his implementation technically is similar to oher db object.
BUT the PROBLEM is how to use it and how it will affect the db in the current architecture ..
this is a very very future task in order to make it happen without bad affection to performance and consistancy.
do we some day just hve to speak to a pc and it do the work?? yes perhaps in some future.. to find out new technologie.

in current architecture i cannot understand how such object will be capable to be maitained and giv good result..
again giving the exmple below o the count.

how will the system ensure correct concistancy by counting every time the whole huge table just to check one constraint regarding the data row by row.


Chris Saxon
June 16, 2016 - 1:06 pm UTC

Consider an implementation of assertions similar to constraints.

I could then do:

set assertion MY_ASSERTION deferred;
insert lots of rows
insert lots of rows
update lots of rows
etc
etc
commit;

and then the assertion will be checked.

Now...lets say "No, thats awful...it will be slow."

So to repeat that exercise without assertions its:

insert lots of rows
insert lots of rows
update lots of rows
run a query to check before committing
commit;

Whoops !!!!! Guess what you just did - you just corrupted the data. Because you cant *just* run a query to validate the data. You didnt take into account concurrency or locking etc.

So you have a choice:

1) learn about / implement all the complexity to get your process correct

2) just ignore it and hope no-one finds out you're doing it wrong

3) allow the assertion to handle the complexity.


didnt understand

ghassan, June 16, 2016 - 2:02 pm UTC

hello i didnt understand last post

in the 1950's mcdonald created the fast food that we know today. in one meal have cheese meat salade tastes ...and make hungry disappear.

hope your assertion come to be reality cause its the hope of lot of people to do as few as possible of coding and setting parameters and confs.


Chris Saxon
June 16, 2016 - 3:35 pm UTC

If your assertion requires a count(*) of a big table then presumably:

- You need to run this query anyway as part of your validation the data are correct
- Unless you add some form of serialization, this query could allow invalid rows. This is because it can't see modified, but not yet committed data in other sessions.

My take on the original question.

Toon Koppelaars, June 16, 2016 - 2:42 pm UTC

The database design is a bit odd.
Odd database designs will result in odd SQL assertions.
Odd can be anything from bad-performing, to ugly-serialization, to unreadable/difficult to specify.

Let's call your table T1:

SYNONYM_NAME  TABLE_NAME
==========================
A   A_A 
B   B_A 
C   C_A 
D   D_A 

So the constraint is as Chris proposed the postfix of column values in TABLE_NAME should always be the same.
Why store that postfix in a redundant manner then?

Let's add table T2:
T2
POSTFIX
========
A


And constraint T2 to only have a single row in it:
create assertion ... as check((select count(*) from T2) = 1)

Then modify the contents of T1 as follows:

SYNONYM_NAME  TABLE_NAME
==========================
A   A 
B   B 
C   C 
D   D

And finally create a view to mimic you orignal output:

create or replace view ... as
select t1.synonym_name
      ,t1.table_name||'_'||t2.postfix as table_name
from T1 t1
    ,T2 t2



Now the question that begs to be asked: I suspect there also is another constraint on your original T1?

CHECK(SYNONYM_NAME = SUBSTR(TABLE_NAME,1,instr(table_name,'_')-1))


?

In that case just get rid of the T1.TABLE_NAME column all together and have your view do this:

create or replace view ... as
select t1.synonym_name
      ,t1.synonym_name||'_'||t2.postfix as table_name
from T1 t1
    ,T2 t2



Anyhow, if you really want to stick to your odd database design, I'd word the assertion as follows:

check
(not exists
   (select 'x'
      from T1 t1
     where exists
            (select 'y'
               from T1 t2
              where t1.synonym_name <> t2.synonym_name
                and substr(t1.table_name,-1,1) <> substr(t2.table_name,-1,1)))
)

Evaluation of this expression will stop on encounter of the first 'mismatch', instead of continue scanning to compute the count(*).

But still modifying your design will end up being the better solution: performance-wise, serialization-wise, maintainability-wise.

Chris Saxon
June 16, 2016 - 3:38 pm UTC

Great point Toon. Changing the data model is a better approach here.

My point

Ghassan, June 16, 2016 - 6:12 pm UTC

Hi great guys
Assertions using x axe eg rows cannot be a awesome discovery and if some day it comes to happen it will be of very restricted usage when it comes against rows. It is a good thing similarly to what the virtual column offer except that took space disk and increase dictionary.
if it happen probably implemented using the analytic functions algorithms .interactions then when ddl and dcl act on tables and other containers will be a new problem to cope with for developers and dbas.
When developers currently code their checks and routines they are responsible of their work and step by another they overcome - partially or totally - the issues But when it comes from the db engine and architecture it us not sale approach to solve.
I am really desirable to see this implemented just to prove such fiasco.
As I said Unless oracle reinvent a new rdbms. On the current 11 and 12 it is a fiasco.
Chris Saxon
June 17, 2016 - 2:47 am UTC

"Assertions using x axe eg rows cannot be a awesome discovery"

I have no idea what that statement is saying.

NOT a good case for assertions !!!

erwin smout, June 17, 2016 - 4:52 pm UTC

As Toon said, this particular problem is better addressed by design. If we look at
SELECT DISTINCT SUBSTR(TABLE_NAME,...) AS PT_TBL FROM ...
then it can be observed that the resulting table is one that must obey the FD
{} -> {PT_TBL}
. Which reveals that the design as stated has obfuscated an important business rule. Not the best of practices.

I know, I know. Enforcing FDs is done by declaring keys, but this particular one cannot be done for two reasons :

(a) it is an empty key, and SQL doesn't support that
(b) it is a key on a view

But is that a reason for suggesting ASSERTION is the right way to go for a solution, or is that a reason for suggesting that relational deficiencies of SQL such as those two, should be fixed ?

ASSERTIONs are a powerful and good tool to have, but we should not be treating them as solution seeking problem. Nor should they be used as an excuse to allow db designers to forget/forgo basic principles of db design.
Connor McDonald
June 18, 2016 - 1:11 am UTC

I have no issue with the validity of your statement, but I'm not convinced it truly reflects real world realities.

There is many a system out there that would benefit greatly from a re-design or even just subtle changes in design to better model the data. But in many cases, such a re-design is never approved, budgetted, attempted...it is left to the developer and/or DBA to "make so" with what is there.

So when you say "Nor should they be used as an excuse to allow db designers to forget/forgo basic principles of db design", I totally agree, but I also think the following suffix is equally valid:

"but they may also benefit as a stopgap/compromise solution if correctness or corrections to db design are not possible"