Error: "exact fetch returns more than requested number of rows" [duplicate] - sql

This question already has answers here:
Why no output when PLSQL Anonymous block completes? [duplicate]
(7 answers)
Printing the value of a variable in SQL Developer
(9 answers)
Closed 4 years ago.
I am using SQL Developer and want to output the contents of a variable to the console using DBMS_OUTPUT.PUT_LINE(). I am running the following code that adds the numbers 1 through 5 inclusive but I'm not seeing any output.
SET SERVEROUTPUT ON;
DECLARE
n_counter NUMBER := 5; -- Substitute this variable
n_sum NUMBER := 0;
BEGIN
WHILE n_counter != 0
LOOP
n_sum := n_sum + n_counter;
n_counter := n_counter -1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(n_sum);
END;
Additionally, do you Know of better resources for troubleshooting issues than the incredibly dense Oracle PL/SQL documentation? [similar to Java SE7 API?]

Since you are using SQL Developer, you have a couple of options.
In SQL Developer, go to View | DBMS Output to ensure that the DBMS Output window is visible. In the DBMS Output window, choose the "plus" icon and select the connection that you want to write data to the DBMS Output window. Then run the PL/SQL block in the SQL Worksheet window using the right arrow (Ctrl+Enter in Windows). You'll see the output appear in the DBMS Output window.
Alternately, you can put both the SQL*Plus SET SERVEROUTPUT ON command and the PL/SQL block in the SQL Worksheet and run it as a script (F5 in Windows). That will display the output immediately below the "anonymous block completed" message in the Script Output window.
Note: Dbms Output in Oracle Sql Developer doesn't show null in the output window. It moves to a new line, but until it will return something else than null, you'll not know all the previous nulls are there.

Related

Ad hoc querying Oracle PL/SQL - for SQL Server developer

I used to do Oracle development many many years ago. I have spent most of the past 15 years doing mainly SQL Server, and where I have done Oracle work, been insulated from the workings by Web services etc.
My question seems to have been asked on the web a few times, but it seems difficult somehow to communicate - at least judging by the answers. I very much appreciate that tools and functionality differ, know I have to learn new things, but this is so simple, yet seems so hard to do.
I am looking to do some ad-hoc queries on the database. At the moment we are using SQL Navigator - I am open to using other tools...
In SQL Server Management Studio, if you open a query window, type a bit of SQL that retuns a value or a set, you get a nice display of the rows or values in a results window.
I've gathered that with Oracle PL/SQL things are a bit different, worked out that I need to return a cursor - but how do I get a tool to display the results?
I started simple:
declare
my_id number := 356655;
cursor c1 is select my_id from dual;
begin
open c1;
end;
This runs fine - but how do I see the results? Are there any tools that deal with this as 'nicely' as SSMS? I am used to being able to do a lot of this, including stuff like
(perhaps not exactly the right syntax? but you get the idea...)
declare
my_id number := 356655;
cursor c1 is select name from my_table where id = my_id;
begin
open c1;
And having the results displayed to me as text/grid. Ideally that there is a nice solution. Some spiffy new tool, maybe?
With SQL Developer or SQL*Plus you can use a bind variable declared before the PL/SQL block:
variable rc refcursor;
declare
my_id number := 356655;
begin
open :rc for select my_id from dual;
end;
/
print rc
RC
-------------------------------
356655
You can also use a bind variable within the query, which can be useful:
variable my_id number;
variable rc refcursor;
execute :my_id := 356655;
begin
open :rc for select :my_id from dual;
end;
/
print rc
The variable and print commands are covered in the SQL*Plus documentation, which largely applies to SQL Developer as well - that has its own documentation, including the commands that are carried over from SQL*Plus.
If you have a function that returns a ref cursor then you can call that in a query, as select func(val) from dual, and then the results can go in a grid; or you can call the function (or procedure) with the same :rc bind variable and print it. But I'm not sure either is helpful if you are only doing ad hoc queries.
On the other hand, using a PL/SQL block for an ad hoc query seems a little heavy-handed, even if your queries are complicated. You'd need a good reason to open a cursor for a select statement from within a block, rather than just running the select directly. (Not sure if that's a SQL Server thing or if you actually have a real need to do this!). If you're just running a query inside the block, you don't need the block, even if you want to keep a bind variable for the values you're using in the query:
variable my_id number;
execute :my_id := 356655;
select :my_id from dual;
:MY_ID
----------
356655
I use Oracle SQL Developer.
Anyway, this should work in any oracle sql client:
If you just want to see your results, you can use
dbms_output.put_line('Foo' || somevar || ' bar');
Before this, run
SET SERVEROUTPUT ON
Check the examples at docs.oracle.com
I would suggest using sql developer available free from the oracle website. There is a button which allows you to run sql as a script which will get back what you want. SSMS doesn't work with pl/sql.

PL/SQL, Cannot print variable

I'm trying to learn PL/SQL by simply assigning a variable from a select statement and then, to confirm it's working, print it sql output.
DECLARE ALLOW_STUFF NUMBER;
BEGIN
SELECT VAL_N INTO ALLOW_STUFF FROM MY_TABLE WHERE MY_KEY = 'ALLOW_ME';
DBMS_OUTPUT.PUT_LINE(ALLOW_STUFF);
END;
I'm using SQL Developer and/or SQL PLus. When I run this, all I get is
Anonymous block completed
Rather than than the value of MY_TABLE.VAL_N
You need to enable output, otherwise the DBMS_OUTPUT.PUT_LINE statements are ignored.
Output can be enabled using:
DBMS_OUTPUT.ENABLE();
For more information about DBMS_OUTPUT read Oracle documentation: http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_output.htm#i1000634
As stated in the comments also set serveroutput on can be used.

Script doesn't generate any output

I'm using the Oracle Developer Days image to get started with PL/SQL in SQL Developer.
Right now I have the following PL/SQL anonymous block:
DECLARE
v_country_name VARCHAR2(40);
v_region_id NUMBER;
BEGIN
SELECT country_name, region_id
INTO v_country_name, v_region_id
FROM countries
WHERE country_id = 'CA';
DBMS_OUTPUT.PUT_LINE('The country name is: ' || v_country_name ||
' and is located in ' || v_region_id || '.');
EXCEPTION
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('Your SELECT statement retrieved multiple rows. ' ||
' Consider using a cursor.');
END;
This executes, but it doesn't do what I want it to do. The Script Output only contains 'anonymous block completed'.
I have tried to explicitly enable the output with DBMS_OUTPUT.enable; but this didn't make a difference.
What am I overlooking?
If you're running it as a script you can add set serveroutput on before your declare, which will show the output in the 'Script Output' window. This will enable output for the remainder of your session, or until you turn it off again.
If you're running it as a statement rather than a script, and don't already have (or don't want) serveroutput on, you can attach SQL Developer to the output. From the View menu choose 'DBMS Output', which opens a new panel with the same name. Running your code again will still produce nothing at this point.
Click the green plus sign (+) and choose your connection from the list. The next time you run it you will see the output. The first time it will probably show multiple versions as the previous runs will have stored the output in a buffer on the server, and they will all be retrieved. Subsequent runs will just show the new output generated by each run.
There's more in the SQL Developer documentation; and there is background in the PL/SQL packages and types reference, which you've probably already seen. Personally I only ever use the script output, partly because it's quicker, partly because it puts mixed output from SQL and PL/SQL in one place (if out of step), but mostly from habit and to maintain script compatibility with SQL*Plus.

Rudimentary issue: basic PL/SQL console output? [duplicate]

This question already has answers here:
Why no output when PLSQL Anonymous block completes? [duplicate]
(7 answers)
Printing the value of a variable in SQL Developer
(9 answers)
Closed 4 years ago.
I am using SQL Developer and want to output the contents of a variable to the console using DBMS_OUTPUT.PUT_LINE(). I am running the following code that adds the numbers 1 through 5 inclusive but I'm not seeing any output.
SET SERVEROUTPUT ON;
DECLARE
n_counter NUMBER := 5; -- Substitute this variable
n_sum NUMBER := 0;
BEGIN
WHILE n_counter != 0
LOOP
n_sum := n_sum + n_counter;
n_counter := n_counter -1;
END LOOP;
DBMS_OUTPUT.PUT_LINE(n_sum);
END;
Additionally, do you Know of better resources for troubleshooting issues than the incredibly dense Oracle PL/SQL documentation? [similar to Java SE7 API?]
Since you are using SQL Developer, you have a couple of options.
In SQL Developer, go to View | DBMS Output to ensure that the DBMS Output window is visible. In the DBMS Output window, choose the "plus" icon and select the connection that you want to write data to the DBMS Output window. Then run the PL/SQL block in the SQL Worksheet window using the right arrow (Ctrl+Enter in Windows). You'll see the output appear in the DBMS Output window.
Alternately, you can put both the SQL*Plus SET SERVEROUTPUT ON command and the PL/SQL block in the SQL Worksheet and run it as a script (F5 in Windows). That will display the output immediately below the "anonymous block completed" message in the Script Output window.
Note: Dbms Output in Oracle Sql Developer doesn't show null in the output window. It moves to a new line, but until it will return something else than null, you'll not know all the previous nulls are there.

Difference between "IN" and "IN OUT" CURSOR parameter in Oracle

From Oracle:
"When you declare a cursor variable as the formal parameter of a subprogram that fetches from the cursor variable, you must specify the IN or IN OUT mode. If the subprogram also opens the cursor variable, you must specify the IN OUT mode."
But, I can code that (only OUT parameter):
create or replace procedure mycur_out(mc OUT mycurpkg.mytypecur) as
begin
open mc for select * from mytable;
end mycur_out;
and works equal to (IN OUT parameter)
create or replace procedure mycur_inout(mc IN OUT mycurpkg.mytypecur)
as
begin
open mc for select * from table10;
end mycur_inout;
Also, It's work fine with dynamic cursor too:
create or replace procedure mycur_out_ref(mc out mycurpkg.mytyperefcur)
as
begin
open mc for 'select * from table10';
end mycur_out_ref;
I've tested the 3 cases directly from oracle and from VB6 with ADO, and no problems.
So, in that cases, is there any difference between IN using just "OUT" and "IN OUT" cursors parameters?
UPDATE
The reason I'm asking:
We read data using routines similar
to the examples (just open the
cursors). The cursor parameters
always are "IN OUT" (Don't ask me
why, I'm trying to figure out)
The routines are invoked with ADO/VB6
Now, we are trying to use some of the routines from JDBC, but the
adapter apparently just accepts OUT
parameters in this cases.
Finally, the main reason, I want to change the cursor parameters on DB
routines to only OUT, but first I
want to know the collaterals effects
of that change.
Thanks!
In the text you quote from the manual, note that it is specifically talking about "a subprogram that fetches from the cursor variable". None of your examples do this, so the quote is not relevant to them.
However, it nonetheless appears that there's nothing wrong with using OUT only in such a situation, if the subprogram both opens and fetches from the cursor variable:
SQL> variable c refcursor
SQL> set serveroutput on
SQL> create or replace procedure no_good (c OUT sys_refcursor)
2 as
3 my_dummy dual.dummy%type;
4 begin
5 open c for select dummy from dual union all select dummy from dual;
6 fetch c into my_dummy;
7 dbms_output.put_line( my_dummy );
8 end;
9 /
Procedure created.
SQL> exec no_good( :c )
X
PL/SQL procedure successfully completed.
SQL> print c
D
-
X
I think the the text is actually trying to make two points that are somewhat independent of each other. Firstly, if you want to pass any already-opened cursor variable into a subprogram, which will fetch from it, the parameter must be declare IN or IN OUT. Secondly, if you want to pass a cursor variable into a subprogram, which will then open it, the parameter must be declared OUT or IN OUT. This is true regardless of whether you actually care about passing the value of the cursor variable back to the caller:
SQL> create or replace procedure no_good (c IN sys_refcursor)
2 as
3 my_dummy dual.dummy%type;
4 begin
5 open c for select dummy from dual;
6 fetch c into my_dummy;
7 dbms_output.put_line( my_dummy );
8 close c;
9 end;
10 /
Warning: Procedure created with compilation errors.
SQL> show error
Errors for PROCEDURE NO_GOOD:
LINE/COL ERROR
-------- -----------------------------------------------------------------
5/6 PL/SQL: SQL Statement ignored
5/11 PLS-00361: IN cursor 'C' cannot be OPEN'ed
This error can be fixed by changing the parameter mode, but actually it would seem to make more sense to simply make the cursor variable a local variable rather than a parameter.
If I understand the question right, the difference is that with the IN OUT version you can pass in a cursor from outside the procedure, and then change that variable (similar to the difference between OUT and IN OUT for a simple numeric variable).
The OUT parameter cursor starts out as a NULL value / closed cursor.
The IN OUT parameter version starts with whatever state is passed in from outside.
You may want to retry your procedure calls repeatedly passing in the same cursor variable - the OUT version should replace the existing value, the IN OUT version should give an exception on the second time round that you are trying to open an open cursor.
Another thing the IN OUT approach allows, that the OUT approach does not, is to take action based on the passed in cursor, and change the returned cursor.
PROCEDURE lp_test2 (mc IN OUT mycurpkg.mytypecur)
IS
lr table10%ROWTYPE;
BEGIN
IF mc%ISOPEN THEN
FETCH mc INTO lr;
IF mc%NOTFOUND THEN
CLOSE mc;
/* Switch cursor to alternative table */
open mc for select * from schema2.table10;
END IF;
END IF;
END lp_test2;
I am just struggling to think of a real situation where you might want to (take in a cursor variable, cast it back into a SQL statement, append some extra dynamic SQL, and return the whole lot back as the same cursor??).