I have an Oracle express database set up at my home laptop for one university project. I've exported the database in a sql script and tried to import it on my workplace and everything works except the package. Package is created but Oracle does not seem to recognise all variables that are declared and he only recognises the first variable (see code below) and in my case that is SIFRADOB NUMBER:=0; My triggers are showing errors because they can't see the variables that are declared in the package. I have dropped the package and created it again and still got the same issue. I've even dropped the database but the issue has reappeared. And here is the image of the problem http://s17.postimg.org/67izq4wcf/package_error.png
create or replace PACKAGE "PAKET" AS
SIFRADOB NUMBER:=0;
NAZIVDOB VARCHAR2(50);
STARASIFRA NUMBER:=0;
STARINAZIV VARCHAR2(50);
SIFRAJM NUMBER:=0;
NAZIVJM VARCHAR2(80);
SIFRAPRO NUMBER:=0;
BROJPOR NUMBER:=0;
END;
I don't think that issue is in some strange 'recognition'. As I understood, package was compiled without errors and can be recompiled, so it contents should be available.
First of all, I'd check if you used some non-latin characters. Identifiers, say, PACKET and РАСКЕТ are completely different in spite of looks equal. It may explain why you have РАСКЕТ.XYZ described but PACKET.XYZ could not be referenced.
Generally, once you even dropped database, you can start from empty schema. So please do it and execute with your package script like
create table T (...);
create package P
x number;
y number;
z number;
end;
/
create trigger t_bi before insert on t
begin
P.y := 1;
end;
show errors;
/
I doubt if it'll lead some errors but if so, please publish log of these actions.
Your code compiles and all variables are present just fine so it isn't that, its probably just SQL Developer or your permissions on the object aren't correct.
Verify that the code you compiled is loaded by executing:
select text from user_source where name='PAKET';
If you see all the variables listed in there then it is loaded properly.
After working through all of the answers posted none solved the problem. I've eventually went to the triggers and just "renamed" so to say literally retyped word "PAKET" in my variables, compiled the triggers and it worked! Really awkward if we take into consideration that I basically haven't changed anything. Sometimes Oracle works in mysterious ways. :)
Related
The test case is as follows:
CREATE OR REPLACE PROCEDURE TEST IS
BEGIN
APEX_JSON.OPEN_OBJECT();
APEX_JSON.CLOSE_OBJECT();
END;
I get a 500 error from ORDS running it from APEX's SQL Commands or SQL Scripts. I'm not sure if there's something else needed here or the recommendation is simply do not use APEX_JSON in procedures. I hope someone can chime in.
Just to clarify: I'm running this on an Oracle Cloud ATP instance, this seems to work fine in on-premise instances but not here.
EDIT 1
I had already tried something similar to Ergi Nushi's answer but to no avail. I even thought my code was wrong and tried his instead but it didn't work either (See screenshot below)
EDIT 2
So far what I have done to get my project going is to use the 12c JSON APIs instead like in:
-- ...
L_JSON := JSON_OBJECT(
KEY 'test' VALUE L_TEST_VALUE
NULL ON NULL
RETURNING VARCHAR2(32767)
);
-- ...
I know this is not the answer I was looking for but hopefully, it helps someone to get going.
First you need to initialize your APEX_JSON with:
APEX_JSON.initialize_clob_output();
After building your object you should get output with
APEX_JSON.get_clob_output();
and then free output in order to use it for other objects:
APEX_JSON.free_output();
Full code:
CREATE OR REPLACE PROCEDURE TEST IS
output CLOB;
BEGIN
APEX_JSON.initialize_clob_output();
APEX_JSON.OPEN_OBJECT();
APEX_JSON.CLOSE_OBJECT();
output := APEX_JSON.get_clob_output(); --> pass the output to a variable
APEX_JSON.free_output();
END;
For a school project, unable to figure out how to debug the code, I've managed to figure out that the problem is in this line of code: Reservation_id:=: reservation_ID; but I am unsure how to fix it
Set serveroutput ON;
Create or replace procedure Reservation_Services_Report (reservation_ID IN number)
As
Service_number reservation.service_type_id%type;
People_attending reservation.numb_people_attend%type;
Begin
Reservation_id:=: reservation_ID;
Select s.service_name, s.service_type, s.service_type_food, s.service_type_entertainment, r.numb_people_attend from services s, reservation r
where services.service_type_id = reservation.service_type_id;
Exception
When no_data_found then
dbm_output.put_line(‘No services for this reservation’);
End;
Oh, it only it were your only problem!
as you declared an IN parameter, why don't you use it? It is here to be passed to the procedure, not to accept it at runtime (which is what you planned to do with preceding its name with a colon).
besides, it is a good idea to distinguish parameter name from column name, otherwise you'll have problems as Oracle won't know which is which. That's why I renamed it to par_reservation_id
select in PL/SQL requires into clause. In your case, you need to declare all those variables which match select column list. I named them all with the l_ prefix (as a l_ocal variable); some people use v_; pick whichever you want, just try to stick to some standards - it'll make your code easier to read, debug and maintain
select you wrote would probably return too_many_rows error as there's no restriction to number of rows; I presume you "forgot" to include the where clause so I put it there; I don't know whether it is correct or not as I don't have your tables. Fix it, if necessary
when joining tables, try to switch to modern ANSI syntax and separate joins from (where) conditions, as I tried
unless you're running that code in a tool that supports dbms_output to be displayed on the screen, you won't see anything. Exception is handled (kind of), but nobody will know what happened. Consider raising the error instead, e.g. raise_application_error(-20000, 'No services for this reservation')
Here's how the procedure might look like; hopefully, it is somewhat better than the original version. See if it helps.
Create or replace procedure
Reservation_Services_Report (par_reservation_ID IN number)
As
l_service_name services.service_name%type;
l_service_type services.service_type%type;
l_service_type_Food services.service_type_Food%type;
l_service_type_entertainment services.service_type_entertainment%type;
l_numb_people_attend reservation.numb_people_attend%type;
Begin
Select s.service_name,
s.service_type,
s.service_type_food,
s.service_type_entertainment,
r.numb_people_attend
into l_service_name,
l_service_type,
l_service_type_food,
l_service_type_entertainment,
l_numb_people_attend
from services s join reservation r on s.service_type_id = r.service_type_id
where r.reservation_id = par_reservation_id;
Exception
When no_data_found then
dbms_output.put_line(‘No services for this reservation’);
End;
I am working on a system where Oracle 11g is the back end database.
I have very limited permissions on the database and as such all I can do is call procedures that reside in packages.
Gerally, these procedure return their result set via an OUT parameter of type sys_refcursor.
I can call them fine in C# and get data from the cursor via the C# OracleDataset type.
Here is my question.
I want to be able to run these procedures and see the results via SQL Developer.
I can execute the procedure fine, but seeing the contents of the sys_refcursor OUT parameter is boggling me.
I've done some gooling and people ar saying about creating type and other solutions I simply do not have the permissions to persue.
So, how can I possibly see the result set contained in a sys_refcursor?
So say I have a procedure with this signature....
procedure an_oracle_Proc(p_ref IN varchar2,
p_result_set OUT sys_refcursor);
I call it like this....
DECLARE
l_ref VARCHAR2(10);
l_result_set sys_refcursor;
BEGIN
oracle_pkg.an_oracle_Proc(p_ref => l_ref,
p_result_set => l_result_set);
--How to select from l_result_set with limited permissions
END
How can I look at the contents of l_result_Set?
This is repeating the answer I linked to before really but specifically for your code:
VARIABLE result_set refcursor;
DECLARE
l_ref VARCHAR2(10);
BEGIN
l_ref := 'whatever';
oracle_pkg.an_oracle_Proc(p_ref => l_ref,
p_result_set => :result_set);
END;
/
PRINT result_set
... and run all of that as a script from an SQL Worksheet. The contents of the ref cursor will be shown in the script output window.
Thought I'd have another look and found this - amazing what stepping away from the computer can do. ;)
I just have to select the appropriate variable on the left pane.
http://www.thatjeffsmith.com/archive/2011/12/sql-developer-tip-viewing-refcursor-output/
Still - it would be nice to write my own SQL to do this rather than using the execute window.
Sys_refcursor form an anonymous block is bit tricky. Use the sql-developer, explore the package or procedure , right click and execute the procedure/package.
Sql-developer will open an input/output UI where you can key in values. And you can see the output on the same UI as well. Let me know if you need more details. I was actually debugging the same a couple of weeks back successfully.
on one of our servers, while compiling:
CREATE OR REPLACE PROCEDURE PROC_KO
IS
TABLE_SUFFIX_ VARCHAR2 (100);
QUERY_DROP_ VARCHAR2 (1000);
BEGIN
TABLE_SUFFIX_ := 'TABLE_SUFFIX';
QUERY_DROP_ := 'DROP TABLE ' || 'TMP_' || TABLE_SUFFIX_;
END;
I get the following error:
I/O Error: Connection reset
What could be the cause of this?
Its possible that in your case you're disallowed to create a procedure by a DDL trigger.
CREATE OR REPLACE TRIGGER bcs_trigger
BEFORE CREATE
ON SCHEMA
DECLARE
oper ddl_log.operation%TYPE;
BEGIN
-- in some case
DBMS_SERVICE.DISCONNECT_SESSION(my_session);
END bcs_trigger;
Sounds like I had the same, or at least a similar, problem. I had already successfully created/compiled the procedure and later returned to make some changes using SQL Developer (17.2.0.188). When attempting to compile the procedure I received the same error (Connection Reset).
It was only after creating a new procedure by copying blocks of code was I able to isolate the 2-3 lines that seemed to be causing the problem. A slight rewrite of one of the lines (by using different variable names) seemed to do the trick.
There was nothing about the lines in question that seemed to stand out. Simple for loop using a SQL statement.
Still don't know the root cause of the problem, but making minor changes to the code seemed to allow it to compile.
Created One Trigger in Oracle..
SQL> CREATE OR REPLACE TRIGGER student_after_insert
2 AFTER INSERT
3 ON student
4 FOR EACH ROW
5 BEGIN
6 #hello.pl
9 END student_after_insert;
10 /
Contents of hello.pl are:-
BEGIN
DBMS_OUTPUT.PUT_LINE('hello world');
END;
And.. the result is pretty good, as the content of hello.pl is displayed on screen while inserting a record..
Now, the query is -- When i change the content of the hello.pl file, after exiting from oracle, and then logging again, It doesn't shows the updated contents, instead it shows the previous content..
I noticed that, if i drop the trigger and create it again, then it is working fine.. Why is it happening so.. And what is the solution to this problem..
It happens because the # works much like the #include in a c/c++ preprocessor, that is, SQL*Plus inserts the content of the file hellp.pl at compile time.
If you want to output the content of a file when the trigger is fired, you might want to look into utl_file.
But it's probably easier for you to create a package similar to
create or replace package trigger_content as
text varchar2(100);
end;
/
You can then dynamically alter the value of text:
exec trigger_content.text := 'hello world';
and print the value of text with
dbms_output.put_line(trigger_content.text);
However, the latter "solution" doesn't work across sessions.
#hello.pl simply includes the text of hello.pl in the body of the CREATE...TRIGGER command. There is no link from Oracle to the file.
Note that, in the general case, the Oracle server is on another machine and has no access to the contents of your hard drive.
Look into EXECUTE IMMEDIATE and DBMS_SQL for dynamic coding.