Kim Berg Hansen: SQL β™  πŸ€“ πŸ‘¨β€πŸ³ 🍺's Avatar

Kim Berg Hansen: SQL β™  πŸ€“ πŸ‘¨β€πŸ³ 🍺

@kibeha.dk

Danish geek πŸ€“ Oracle SQL & PL/SQL Developer β™  ACE Director 4️⃣2️⃣ #SYM42 πŸ‘¨β€πŸ³ Likes to cook πŸš€ Reads sci-fi 🍺 Beer Enthusiast 🏒 Cegal Danmark A/S πŸ§‘β€πŸ’» https://kibeha.dk

571
Followers
238
Following
475
Posts
16.08.2023
Joined
Posts Following

Latest posts by Kim Berg Hansen: SQL β™  πŸ€“ πŸ‘¨β€πŸ³ 🍺 @kibeha.dk

Preview
a man in a prison cell says hope is a dangerous thing ALT: a man in a prison cell says hope is a dangerous thing
07.03.2026 08:58 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Preview
a man in a military uniform has a medal on his chest ALT: a man in a military uniform has a medal on his chest
06.03.2026 20:18 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

I think this was the first time I deliberately did it - muscle memory just puts in FROM DUAL every time πŸ˜‡

06.03.2026 19:17 πŸ‘ 2 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Nope - not needed anymore 😁

But it’s still used even if I don’t write it. I should add a little explanation…

06.03.2026 18:28 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Preview
Assertions for data integrity on a less-than-ideal data model 25-30 years ago I worked a lot with the Danish developed ERP system called Concorde XAL. It ran on top of a database (choice of several, mos...

Assertions for data integrity on a less-than-ideal data model.

www.kibeha.dk/2026/03/asse...

Or "How I could have used assertions 25 years ago when I worked with Concorde XAL"...

#OrclDB #SQL #Assertions #OracleACE

06.03.2026 15:50 πŸ‘ 5 πŸ” 4 πŸ’¬ 2 πŸ“Œ 0
Preview
Assertions for data integrity on a less-than-ideal data model 25-30 years ago I worked a lot with the Danish developed ERP system called Concorde XAL. It ran on top of a database (choice of several, mos...

www.kibeha.dk/2026/03/asse...

06.03.2026 15:48 πŸ‘ 2 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Blog post coming up - with sample code.

06.03.2026 13:54 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Post image

These work fine too.

I'd hazard the guess that they can be checked and evaluated more efficiently.

Also it has the advantage of error messages specifying which assertion is violated.

06.03.2026 12:17 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
create assertion Notes_RefRecId_MultiFK check (
   not exists (
      select null
      from Notes n
      where not exists (
         select null
         from DebTab d
         where n.RefFileId = 11
         and d.RecId = n.RefRecId
      ) and not exists (
         select null
         from CreTab c
         where n.RefFileId = 15
         and c.RecId = n.RefRecId
      ) and not exists (
         select null
         from StoTab s
         where n.RefFileId = 27
         and s.RecId = n.RefRecId
      )
   )
);

create assertion Notes_RefRecId_MultiFK check ( not exists ( select null from Notes n where not exists ( select null from DebTab d where n.RefFileId = 11 and d.RecId = n.RefRecId ) and not exists ( select null from CreTab c where n.RefFileId = 15 and c.RecId = n.RefRecId ) and not exists ( select null from StoTab s where n.RefFileId = 27 and s.RecId = n.RefRecId ) ) );

Actually, this one works in a single assertion, turning it into NOT EXISTS with AND instead of EXISTS with OR.

But one assertion per parent table might be able to evaluate the checks faster and check only when needed. Whether that'd outweigh overhead of many assertions - who knows πŸ˜‰

06.03.2026 12:08 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I had just now come to that conclusion too. 😁
Yes, with individual assertions with filter in ALL query, that should work. Will try it now.

06.03.2026 11:45 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
create assertion Notes_RefRecId_MultiFK check (
   all (
      select n.RefFileId, n.RefRecId
      from Notes n
   ) nref
   satisfy (
      exists (
         select null
         from DebTab d
         where nref.RefFileId = 11
         and d.RecId = nref.RefRecId
         UNION ALL
         select null
         from CreTab c
         where nref.RefFileId = 15
         and c.RecId = nref.RefRecId
         UNION ALL
         select null
         from StoTab s
         where nref.RefFileId = 27
         and s.RecId = nref.RefRecId
      )
   )
);

create assertion Notes_RefRecId_MultiFK check ( all ( select n.RefFileId, n.RefRecId from Notes n ) nref satisfy ( exists ( select null from DebTab d where nref.RefFileId = 11 and d.RecId = nref.RefRecId UNION ALL select null from CreTab c where nref.RefFileId = 15 and c.RecId = nref.RefRecId UNION ALL select null from StoTab s where nref.RefFileId = 27 and s.RecId = nref.RefRecId ) ) );

create assertion Notes_RefRecId_MultiFK check (
   all (
      select n.RefFileId, n.RefRecId
      from Notes n
   ) nref
   satisfy (
      exists (
         select null
         where exists (
            select null
            from DebTab d
            where nref.RefFileId = 11
            and d.RecId = nref.RefRecId
         ) OR exists (
            select null
            from CreTab c
            where nref.RefFileId = 15
            and c.RecId = nref.RefRecId
         ) OR exists (
            select null
            from StoTab s
            where nref.RefFileId = 27
            and s.RecId = nref.RefRecId
         )
      )
   )
);

create assertion Notes_RefRecId_MultiFK check ( all ( select n.RefFileId, n.RefRecId from Notes n ) nref satisfy ( exists ( select null where exists ( select null from DebTab d where nref.RefFileId = 11 and d.RecId = nref.RefRecId ) OR exists ( select null from CreTab c where nref.RefFileId = 15 and c.RecId = nref.RefRecId ) OR exists ( select null from StoTab s where nref.RefFileId = 27 and s.RecId = nref.RefRecId ) ) ) );

create assertion Notes_RefRecId_MultiFK check (
   all (
      select n.RefFileId, n.RefRecId
      from Notes n
   ) nref
   satisfy (
      exists (
         select null
         from dict d
         where d.FileId = nref.RefFileId
         and d.ColId = 0
         and (
            (
               nref.RefFileId = 11
               and exists (
                  select null
                  from DebTab d
                  where d.RecId = nref.RefRecId
               ) 
            ) or (
               nref.RefFileId = 15
               and exists (
                  select null
                  from CreTab c
                  where c.RecId = nref.RefRecId
               ) 
            ) or (
               nref.RefFileId = 27
               and exists (
                  select null
                  from StoTab s
                  where s.RecId = nref.RefRecId
               ) 
            )
         )
      )
   )
);

create assertion Notes_RefRecId_MultiFK check ( all ( select n.RefFileId, n.RefRecId from Notes n ) nref satisfy ( exists ( select null from dict d where d.FileId = nref.RefFileId and d.ColId = 0 and ( ( nref.RefFileId = 11 and exists ( select null from DebTab d where d.RecId = nref.RefRecId ) ) or ( nref.RefFileId = 15 and exists ( select null from CreTab c where c.RecId = nref.RefRecId ) ) or ( nref.RefFileId = 27 and exists ( select null from StoTab s where s.RecId = nref.RefRecId ) ) ) ) ) );

So I got my conditional/subset foreign key working.
But multi-parent foreign key I need to rethink how to phrase. So far my attempts have raised:

ORA-08663: Set operators are not supported.
ORA-08697: SYS owned tables are not supported.
ORA-08695: A subquery within an OR condition is not supported.

06.03.2026 11:08 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Preview
homer simpson is wearing a white shirt with the word doh on the front ALT: homer simpson is wearing a white shirt with the word doh on the front

Thank you - now it actually worked 😁

06.03.2026 10:36 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

(This multi-parent foreign key I have not yet had time to try.)

06.03.2026 10:11 πŸ‘ 0 πŸ” 0 πŸ’¬ 2 πŸ“Œ 0
Post image

I tried and got error:

ORA-08689: CREATE ASSERTION failed
ORA-08673: Equijoin "D"."FILEID"="N"."REFFILEID" found does not meet the criteria to do a FAST validation.

06.03.2026 10:11 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Yup - a foreign key to only some rows of another table. Problem is that the metadata table has pk of (FileId, ColumnId) - if we filter by "where ColumnId = 0", then FileId is unique among those rows - and that's what I want the conditional foreign key to refer to.

06.03.2026 10:08 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

2. The "File" in FileId is actually table names. Some other tables have two columns RefFileId and RefRecId. The RefRecId is a foreign key to some other table (all tables have a RecId primary key) - the RefFileId decides to which table the RefRecId is a foreign key.

06.03.2026 10:05 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

1. It had a "metadata" table with columns FileId and ColumnId and name.
For each FileId value there was 1 row with ColumnId = 0 for File name, rows ColumnId > 0 have Column names.

Other tables have RefFileId - I thought assertions could be "foreign key" to metadata table FileId where ColumnId = 0.

06.03.2026 10:03 πŸ‘ 0 πŸ” 0 πŸ’¬ 2 πŸ“Œ 0

Oh, I had a couple ideas where I thought that assertions could help with improving data integrity of an ancient not-so-good datamodel used in legacy ERP system "Concorde XAL" that I worked a lot with 25-30 years ago.

06.03.2026 09:58 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I tried, but it couldn't be solved with assertions, sorry πŸ˜‡

06.03.2026 09:09 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
SQL statement:
select use_cases from assertions where creator = 'Oracle ACE'
order by real_world_applicability + complexity + novelty desc
fetch first 3 rows only

SQL statement: select use_cases from assertions where creator = 'Oracle ACE' order by real_world_applicability + complexity + novelty desc fetch first 3 rows only

We're still looking for interesting assertions use cases

Just over two weeks left for #OracleACE to get your entries in

Bounty closes 15th March

For full details read blogs.oracle.com/sql/assertio...

27.02.2026 09:56 πŸ‘ 4 πŸ” 3 πŸ’¬ 2 πŸ“Œ 0

Aha.

Okay, where I discovered this was a customer that had migrated from on-premises 19c without extended strings to ExaCC 26ai that's autonomous and with extended strings. They never knew that now a VARCHAR2(4000 CHAR) could cause this to happen. They'll just change to VARCHAR2(4000 BYTE).

05.03.2026 08:15 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

My google-fu must be weak - I didn't find anything about that?

05.03.2026 08:01 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Post image

TIL in 23/26ai with extended strings, you do NOT get "ORA-01450: maximum key length (6398) exceeded" at *create* index on VARCHAR2(4000 CHAR) - it succeeds => dba_ind_columns.column_length=16000

At *insert* you can get ORA-01450 !

blogs.oracle.com/sql/how-to-f...

Careful or #BugWaitingToHappen

04.03.2026 15:12 πŸ‘ 5 πŸ” 0 πŸ’¬ 1 πŸ“Œ 1
Post image
28.02.2026 10:41 πŸ‘ 83 πŸ” 47 πŸ’¬ 3 πŸ“Œ 2
Post image

Yup.

(I've always wondered why the NLS formats did not include something that matched the "Western Traditional" week numbering - WW doesn't, and I simply haven't found *any* place in the world using the rule that WW implements.)

27.02.2026 09:42 πŸ‘ 2 πŸ” 1 πŸ’¬ 0 πŸ“Œ 0

Augh...

Just spotted that the WEEK calendar functions use YYYY and WW rather than IYYY and IW.
Worse - it's not even an option to use IYYY and IW.

I have no idea who is using WW - I have never found any usecase for a week numbering system where weeks begin on whatever weekday Jan 1 happens to be.

27.02.2026 09:26 πŸ‘ 3 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

"Don't go nuts"

Sound advice any day.

27.02.2026 09:18 πŸ‘ 2 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Post image

Why I tend to write loooooooong pieces of text instead - but no use, people still misinterpret πŸ˜‡

26.02.2026 12:40 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Preview
Linda AI - Dating Coach App - App Store Download Linda AI - Dating Coach by SocialPlay AI on the App Store. See screenshots, ratings and reviews, user tips, and more apps like Linda AI - Dating Coach.

Probably she can
apps.apple.com/us/app/linda...

25.02.2026 11:40 πŸ‘ 1 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Preview
an older man sits at a desk using a computer and a mouse ALT: an older man sits at a desk using a computer and a mouse
25.02.2026 11:09 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0