Skip to main content

Command Palette

Search for a command to run...

Oracle SQL Syntax Improvements

Updated
•3 min read•View as Markdown
J
An adaptable, dedicated and talented Oracle Developer with strong SQL and PL/SQL skills and over 25 years’ experience. I am pro-active in my approach and have plenty of natural ability, drive and determination so I am an asset to the teams I work in. I love to learn new skills, relish new challenges and have a passion for delivering high quality software with exceptional business outcomes. I love to improve processes and standards relating to release cycles, peer reviews, effective use of source control and other best practices that ensure low risk, high quality software development and delivery.

Oracle has been busy making a number of syntax changes in recent versions of Oracle. This blog aims to be a one stop shop for a few of the best ones (in my opinion).

No More Dual

Ok, that's Duel rather than Dual (and only oldies will get it anyway). Moving on...

Since version 23c Oracle has made it no longer necessary to do this:

SELECT SYSDATE
FROM DUAL;

Instead you can just do this:

SELECT SYSDATE;

This can look a little bit strange till you get used to it but the above queries are equivalent. A couple of other examples without FROM DUAL:

SELECT 1
UNION ALL
SELECT 2;
SELECT LEVEL CONNECT BY ROWNUM <= 4;

Direct Joins in Update and Delete Statements

You can now (v23ai/26ai) directly join tables within updates and deletes. These are more readable than using subqueries:

UPDATE EMP E
SET E.SAL = E.SAL + (E.SAL * .1)
FROM DEPT D
WHERE E.DEPTNO = D.DEPTNO
  AND D.LOC = 'YORKSHIRE';

Or this:

DELETE FROM EMP E
FROM DEPT D
WHERE E.DEPTNO = D.DEPTNO
  AND D.DNAME = 'RESEARCH';

Insert Improvements

The SET clause - INSERT statements like UPDATE statements...

The following:

INSERT INTO CLAIMS (ID, CREATED_DT, CREATED_BY, RECEIVED_DT, STATUS)
VALUES
(CLAIM_SEQ.NEXTVAL, SYSDATE, USER, :1, :2);

Can be replaced by:

INSERT INTO CLAIMS 
SET ID = CLAIM_SEQ.NEXTVAL, CREATED_DT=SYDATE, CREATED_BY=USER RECEIVED_DT=:1, STATUS=:2;

The SET clause is much easier for column to value alignment making them more readable and far less likely to set any columns to the wrong value.

Oracle also supports multirow inserts like these:

INSERT INTO CLAIMS (ID, CREATED_DT, CREATED_BY, RECEIVED_DT, STATUS)
VALUES
(CLAIM_SEQ.NEXTVAL, SYSDATE, USER, :1, :2),
(CLAIM_SEQ.NEXTVAL, SYSDATE, USER, :3, :4);

And (with SET):

INSERT INTO CLAIMS 
SET (ID = CLAIM_SEQ.NEXTVAL, CREATED_DT=SYDATE, CREATED_BY=USER RECEIVED_DT=:1, STATUS=:2), (ID = CLAIM_SEQ.NEXTVAL, CREATED_DT=SYDATE, CREATED_BY=USER RECEIVED_DT=:3, STATUS=:4);

Note the use of parenthesis here to divide the rows.

I was curious to see if it was possible to use the returning clause returning into a collection e.g. RETURNING ID BULK COLLECT INTO r_ids; but this was not possible for either of the above inserts and resulting in the following errors respectively:

ORA-63853: RETURNING clause is not allowed with a multi-row INSERT INTO SET clause.

ORA-63809: returning clause is not allowed with INSERT and Table Value Constructor


Follow my blog and YouTube Channel for more Oracle coding tips.

613 views