Quantcast
Channel: Obsessed with Oracle PL/SQL
Viewing all articles
Browse latest Browse all 312

SQL%ROWCOUNT: What/how much did my SQL statement do?

$
0
0
This post is courtesy of the PL/SQL Challenge quiz ending 27 November 2015:

If a SELECT INTO statement without a BULK COLLECT clause returns multiple rows, PL/SQL raises the predefined exception TOO_MANY_ROWS and SQL%ROWCOUNT returns 1, not the actual number of rows that satisfy the query.

Furthermore, the value of SQL%ROWCOUNT attribute is unrelated to the state of a transaction. Therefore: When a transaction rolls back to a savepoint, the value of SQL%ROWCOUNT is not restored to the value it had before the save point. When an autonomous transaction ends, SQL%ROWCOUNT is not restored to the original value in the parent transaction.

Here's the code for the quiz - see how you do!

And of course sign up to take each weekly quiz as it is released (you can even compete for international rankings).

I execute the following statements (which you can easily run yourself on LiveSQL):

CREATE TABLE plch_flowers
(
id INTEGER PRIMARY KEY,
nm VARCHAR2 (100) UNIQUE
)
/

BEGIN
INSERT INTO plch_flowers
VALUES (1, 'Orchid');

INSERT INTO plch_flowers
VALUES (2, 'Rose');

COMMIT;
END;
/

Which of the choices result in "RC=1" being displayed on the screen after execution?

DECLARE
l_id INTEGER;
BEGIN
SELECT id
INTO l_id
FROM plch_flowers
WHERE nm = 'Orchid';

DBMS_OUTPUT.put_line ('RC=' || SQL%ROWCOUNT);
END;
/

DECLARE
l_id INTEGER;
BEGIN
SELECT id INTO l_id FROM plch_flowers;
EXCEPTION
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line ('RC=' || SQL%ROWCOUNT);
END;
/

BEGIN
INSERT INTO plch_flowers
SELECT id * 3, UPPER (nm) FROM plch_flowers;

DBMS_OUTPUT.put_line ('RC=' || SQL%ROWCOUNT);
END;
/

DECLARE
l_id INTEGER;
BEGIN
INSERT INTO plch_flowers
VALUES (3, 'Tulip');

SAVEPOINT inserted_row;

INSERT INTO plch_flowers
VALUES (3, 'Lotus');
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK TO inserted_row;
DBMS_OUTPUT.put_line ('RC=' || SQL%ROWCOUNT);
END;
/

DECLARE
l_id INTEGER;

PROCEDURE insert_and_save
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO plch_flowers
SELECT id * 3, UPPER (nm) FROM plch_flowers;

COMMIT;
END;
BEGIN
INSERT INTO plch_flowers
VALUES (10, 'Ambrosia');

insert_and_save;
DBMS_OUTPUT.put_line ('RC=' || SQL%ROWCOUNT);
END;
/


Background on SQL%ROWCOUNT

Static or embedded SQL are SQL statements that are written natively into your PL/SQL programs (as opposed to defining them as expressions for execution as dynamic SQL). An implicit cursor is a session cursor that is constructed and managed by PL/SQL. PL/SQL opens an implicit cursor every time you run a SELECT or DML statement. You cannot control an implicit cursor, but you can get information from its attributes. Oracle defines a number of attributes of implicit cursors, whose value can be obtained through the SQL%attribute syntax.

SQL%attribute always refers to the most recently run SELECT or DML statement. If no such statement has run, the value of SQL%attribute is NULL. An implicit cursor closes after its associated statement runs; however, its attribute values remain available until another SELECT or DML statement runs. The most recently run SELECT or DML statement might be in a different scope (another subprogram call that has now completed, for example).

To save an attribute value for later use, assign it to a local variable immediately. Otherwise, other operations, such as subprogram invocations, might change the value of the attribute before you can test it. SQL%ROWCOUNT returns NULL if no SELECT or DML statement has run. Otherwise, it returns the number of rows returned by a SELECT statement or affected by a DML statement (a PLS_INTEGER).

 If a SELECT INTO statement without a BULK COLLECT clause returns multiple rows, PL/SQL raises the predefined exception TOO_MANY_ROWS and SQL%ROWCOUNT returns 1, not the actual number of rows that satisfy the query. Furthermore, the value of SQL%ROWCOUNT attribute is unrelated to the state of a transaction.

Therefore: When a transaction rolls back to a savepoint, the value of SQL%ROWCOUNT is not restored to the value it had before the save point. When an autonomous transaction ends, SQL%ROWCOUNT is not restored to the original value in the parent transaction.

Viewing all articles
Browse latest Browse all 312

Trending Articles