How this function works? - Oracle - sql

I have just started using Oracle procedures, using following procedure(made by our DBA department) in my code but having difficulty in understanding this procedure, I have googled a lot and read tutorials but still have confusion.
If anyone could explain this to me, I would really be gratefull.
function SF_MY_IDENTITY(name IN VARCHAR2, fName in VARCHAR2 class in VARCHAR2,std_Id in VARCHAR2)return UD_CURSOR
is
cursorReturn UD_CURSOR;
grNo VARCHAR(100);
phone VARCHAR(100);
begin
In above part I couldn't figure out what is this 'is' doing?what it is being used for?
Open cursorReturn for
SELECT
grNo,
phone
FROM
MY_SCHOOL MS
WHERE
MS.std_id=std_Id
AND MS.name=name
AND MS.fNameE=fName;
What is this part doing, what does open doing? and how the output variables 'grNo, phone' would be used in an irrelevant table(MY_SCHOOL)

1) The "is" token is part of the function definition in pl/sql
2) Opens a sql cursor.
I highly recommend that you read a book about pl/sql. For instance the oracle documentation.

It just takes few inputs and based on the input values it opens a cursor and returns it back.
But there is some comma missing and the code is incomplete. Based on what you have posted, this is what the function is doing.

Related

select stored proc plsql

I'm a bit confused by the stored procedure syntax in Oracle.
I started with a simple:
select * from test_table;
It works, then I put it in a proc:
CREATE OR REPLACE PROCEDURE example
IS
BEGIN
select * from test_table;
END;
Doesn't work. Expected "INTO" is the error message I get. Now, I've seen syntax examples of SQL Server code that just shoves a select statement into a proc and it works instantly, but that doesn't seem to be the case here.
T-SQL and PL/SQL are completely different languages. In particular, for PL/SQL you have to select the result into some variable or cursor. Depending on what you plan to do with the record data - process in the procedure - or return to the caller, will drive what you have to do.
In your example, if you want to return the record set, you would do something like this:
CREATE OR REPLACE PROCEDURE example (
p_recordset OUT SYS_REFCURSOR) AS
BEGIN
OPEN p_recordset FOR
select * from test_table;
END example ;
See this link for examples.
Hello and welcome to SO.
I assume the full error you're seeing would be PLS-00428: an INTO clause is expected in this SELECT statement and it is correct, you must have an INTO statement in a stored procedure.
I recommend this link for syntax relating to the SELECT INTO statement.
For your code I recommend this (I've changed from your test_table example to dba_user):
CREATE OR REPLACE PROCEDURE example
IS
l_username VARCHAR(25);
BEGIN
select username INTO l_username from dba_users where user_id=1;
END;
/
Note: The INTO clause works with 1 column from 1 row. You cannot select multiple records or columns into this. You would need to reference the BULK COLLECT feature to do that. For examples of that feel free to read here.
select * from test_table;
SQL and PL/SQL are nor the same. To execute a SQL in a procedure, the parser expects an INTO clause to store the value returned by the sql statement. In PL/SQL, there is a reason to execute a SQL statement. You want to use the result set later to process. Not just retrieve and do nothing.
Also, it is a bad idea to use select * in any production system. You don't want to dump all the columns data of the table on an application screen. There are many other reasons, however, not in the scope of this question.
You need to modify your SQL like following -
SELECT column_name INTO variable FROM table_name
There are several ways to fetch the data via SQL statement in PL/SQL. You need to elaborate your requirement and narrow down to specific steps here.
If you are learning about these concepts, I would recommend you to start reading the Oracle documentation first. Try and understand the concepts, and if you find any issues, then prepare a test case, explain your issue in words and then post a question. Too broad questions are difficult to answer, and are mostly considered out of scope.

Why doesn't this PL/SQL procedure work?

I have a cursor which returns two values: one which I will use (and therefore will assign to an out variable) and another which I've only had returned to make the ROWNUM thing work.
If I run the cursor as a query, it works as expected. But if I execute the procedure the out variable comes empty. Is my approach somehow not supported? I mean, returning two values but only using one of them?
Here is my procedure code: (Don't delve too much on the query itself. It works, I know it's a bit ugly but it works. It was the only way I found to return the second-last row)
procedure retorna_infos_tabela_164(i_nip in varchar,
o_CODSDPANTERIOR out number) is
cursor c_tabela_164 is
select *
from(
select CODSDP,ROWNUM rn
from
(
select NRONIP,CODTIPOMOV,CODSDP
from TB164_HISTORICOMOVIMENTACOES
where NRONIP = i_nip and
CODTIPOMOV='S1'
order by DTHMOV desc
)
)
where rn=2;
v_temp_nr number;
begin
open c_tabela_164;
fetch c_tabela_164 into o_CODSDPANTERIOR,v_temp_nr;
close c_tabela_164;
end retorna_infos_tabela_164;
EDIT The way I've tried to run this procedure was by dbms_output.put_line(o_CODSDPANTERIOR) which didn't work. Then I googled a little bit and saw I should TO_CHAR() my var first and then have it output. Didn't work either.
There's no problem with passing a number to DBMS_OUTPUT.PUT_LINE. Oracle will silently convert other built-in types to VARCHAR2 using the default format. You only need to use TO_CHAR if you want to control the format used -- which is often a good idea, but not generally necessary.
One possibility, though, is that you are not seeing the output because you have not enabled it. If you are running your test in SQLPlus, make sure you SET SERVEROUTPUT ON before running code that includes DBMS_OUTPUT calls. If you are using some other client, consult its documentation for the proper way to enable DBMS_OUTPUT. (You can of course test if it's enabled by adding another call to output a string literal.)
There's nothing inherently wrong with the technique you're using to populate the out parameter. However, it's not necessary to return two columns from the cursor; your select * could simply be select CODSDP. You seem to be under the misconception that any column referenced in the predicates has to be in the select list, but that's not the case. In your innermost query, the select list does not need to include NRONIP or CODTIPOMOV, because they are not referenced in the outer blocks; the WHERE clause in that query can reference any column in the table, regardless of whether it is in the select list.
So, my first guess is that you simply don't have server output enabled. The only other possibility I can think of right now is that you're running your query and the procedure in two different sessions, and one of them has uncommitted transaction against the table, so they are actually seeing different data.
If those suggestions don't seem to be the problem, I'd suggest you run your tests of the standalone query and the procedure in a single SQLPlus session, then copy and paste the entire session here, so we can see exactly what you're doing.
I'm sorry I've had you guys take the time to answer me when the answer was something to do with the tool I'm using. I hope all you guys have learnt something.
The query does work for me at least, I've not come across any edge cases where it doesn't work, but I haven't tested it exhaustively.
The problem was that TOAD, the tool I'm using to run the procedures, sometimes populates the procedures with the parameters I tell it to but sometimes it doesn't. The issue here was that I was trying to execute the procedure with no parameters, yielding no results...
Lesson Learnt: double check the generated procedure code when you run a Procedure using Right Click > Run Procedure on TOAD version 9.

Prompt user in PLSQL

My assignment is to write a PLSQL module to insert data into database. Upon a certain condition, it may need additional information and should prompt the user for one more detail. This should be done directly in PLSQL and wording is straight from the assignment.
I've researched the topic and found some people said this cannot be done in PLSQL? But the ACCEPT PROMPT function does exist.
ACCEPT v_string PROMPT 'Enter your age: ';
While this works directly from SQLPlus, it does not work in PLSQL as it gives me this error:
PLS-00103: Encountered the symbol "V_STRING" when expecting one of the following: := . ( # % ;
Can anyone provide some insight as to how I'm supposed to ask the user from PLSQL, only upon when a certain condition is true (the condition is checked when you get something else from the DB). To clarify, I only need help on how to accept input.
Thanks for your time.
There is a trick that will allow you to do something like this, but (a) it's a bit of a hack, (b) you need to be logged into the database server itself, and (c) it only works on Linux (and perhaps other flavours of Unix).
Generally, it's not possible to ask for user input in PL/SQL, especially if you're connecting to a database on a remote machine. Either your assignment is wrong or you've misunderstood it.
PL/SQL programs are designed to run on the database server, so it doesn't make sense to ask the user for input during them. Using the ACCEPT command, SQL*Plus can ask the user for input while running a script client-side. SQL*Plus will then substitute in the value entered before sending SQL or PL/SQL to the database.
Well, since it's not really a part of SQL, but rather the developer tools you use, here's the ones I know:
SQL*Plus: &Variable
SQL Developer: You can make a procedure or you can use :Variable to be prompted to insert a parameter
I checked and tried following things which might helpful to you. It's just an example which I tried. You can implement your own logic.
declare
c1 varchar2(50);
begin
c1:='&enter_value';
dbms_output.put_line(c1);
exception
when others then
dbms_output.put_line(sqlerrm);
end;
'&' will help you to prompt and ask input to user. Once user feeds some input, it will assign to variable and you can use variable wherever you want.
Hopefully this helps you.
You cannot get user input in pure PL/SQL. It is a server-side language to express business/database logic.
The use of "&" to get input is a "sqlplus" feature and not a PL/SQL strategy. If it was an "assignment" then you need to tell the teacher that it is an invalid assignment - or maybe it was a trick question!

Stored Procedures on Oracle SQL Developer

could you point me to a good place to start with Oracle stored procedures syntax/usage? I can't seem to find any good place there. I'm fairly proficient in (java, C/C++) programming and I do know enough SQL for my needs right now, but I've been suggested to use stored procedures to do my business, which is:
Take results from a query (2 columns) and insert them, row by row, in another table, along with an incrementing key whose value is taken from a third table. And of course this last value must be incremented once for every row.
I have the query to do the first part (extract data to be inserted) and the second part (insert data into table with incrementing key, then increment key on keygenerator table), all I need now is combine both so I can batch-insert the 6000 or so rows I have.
Thanks everyone.
Oracle uses PL/SQL programming language for their stored procedures. Here is an info about PL/SQL in wiki
This is a good source too.
Oracles provides a lot of tools to make the programmer's life easier, but my advice is to start as simple as you can to get familiar with the language..
and... Stored Procedures in PL/SQL
What you want looks pretty simple.This looks like a nice place to start.
http://www.devshed.com/c/a/Oracle/Oracle-Stored-Procedures/
As beginner, you can go through below link, it contains all basics related to procedure.
link
Regarding stored procedures, the basic syntax is:
-- The REPLACE keyword is optional. Without it the CREATE statement
-- will fail if there there is already a procedure with the same name
CREATE [OR REPLACE] PROCEDURE procedure_name AS|IS
-- Variable declarations
BEGIN
-- Stored procedure body
-- Optional exception block
[EXCEPTION]
-- Exception handlers
END [procedure_name];
/
-- The procedure_name after the END statement is optional, used
-- mostly for readability
The programing language is PL/SQL by default, but Oracle also allows you to write stored procedures in java. You can also call external C code (or any language that can generate C linkage object libraries) by creating external procedures that refer to shared libraries in the operating system.
PL/SQL resembles pascal and Delphi. It is based in the Ada language that is based in pascal. PL stands for "procedural language", but it also allows the object oriented programming paradigm.
For a more complete syntax reference, I'm particularly fond of the PSOUG (http://psoug.org) reference library for syntax and usage tips. Here are two links good for starters:
http://psoug.org/definition/procedure.htm
http://psoug.org/reference/procedures.html

Good beginner resources to get started on Oracle Stored Procedure

I am looking for good resources on Oracle Stored Procedure geared towards beginners. I tried the Dev Shed Article and one from Oracle Documentation site but they did not meet my needs. The one form Oracle Documentation site had the overhead of Java example. I tried the Dev Shed one but I keep getting invalid SQL error when I try their example. Here is the basic one that I tried to run:
CREATE OR REPLACE PROCEDURE skeleton
IS
BEGIN
NULL;
END;
EXECUTE skeleton;
Am I making a rookie mistake or is the syntax in the article out of date? I am working with Oracle 10g & PL/SQL Developer.
Thanks!
SOLUTION:
As per #curtisk's suggestion, I tried a slightly more involved example:
CREATE OR REPLACE PROCEDURE p_getdate
IS
BEGIN
dbms_output.put_line(TO_CHAR
(SYSDATE, 'MM-DD-YYYY HH24:MI:SS'));
END;
When I tried to execute it like so:
EXECUTE p_getdate
I got ORA-00900: Invalid SQL statement error. I looked for why this would be the case & stumbled across this thread. I decided to give call a try so I tried the following:
CALL p_getdate;
but that did not work as well. I read the thread some more & skeptically tried:
CALL p_getdate();
and voila, I had the procedure being called properly. I do not have an answer as to why this works but the fact that it works allows me to move forward with my project. If there is anyone who can explain to me why this is, I would love to learn more on this.
Thanks once again to #curtisk for the help!
I wouldn't use that example as a starting point...I'd make it do something here's one to try
CREATE OR REPLACE PROCEDURE p_getdate
IS
BEGIN
dbms_output.put_line(TO_CHAR
(SYSDATE, 'MM-DD-YYYY HH24:MI:SS'));
END;
Run that, it should compile successfully, then at the prompt....
SQL> SET SERVEROUT ON;
SQL> execute p_getdate;
06-11-2009 12:29:54
You should see the current date/time in the output. The example you used was too simple IMHO. Next step is to create a procedure that deals with declarations and parameters.
As far as beginner resources, there's a ton out there can't really recommend any one in particular, and if nothing there's always "Ask Tom"..should be some Q/A there that may help
Your best bet would be a book such as Oracle PLSQL Programming by Steve Feurenstein and Bill Prybil. This has tons of examples and is around 1300 pages.
If you just need a reference, you can try this url to the oracle 12c plsql language reference, though I'm a bigger fan of use cases as found in the previous suggestion.
http://docs.oracle.com/database/122/LNPLS/toc.htm