Oracle Database 12c Enterprise Edition Release 12.2.0.1.0
I have this code:
CREATE OR REPLACE PROCEDURE temp_procedure (
/*-------------------------------------------------
comment
--------------------------------------------------*/
x in VARCHAR2
) IS
BEGIN
NULL;
END;
/
My colleague wrote me that, when he tried to compile it he had a compilation error.
But that code worked for him:
CREATE OR REPLACE PROCEDURE temp_procedure (
/********************************************************
comment
*********************************************************/
x IN VARCHAR2
) IS
BEGIN
null;
END;
/
Earlier when I used SQL*Plus 11.2.0.3.0 to compile my code it showed no errors.
Also, I checked status via
SELECT status
FROM dba_objects
WHERE object_name = 'TEMP_PROCEDURE'
status = Valid.
After getting this note, I tried compiling it in
TOAD 12.1.0.22 and PL/SQL developer 10.0.5.1710.
I got the same result - no compilation errors and the procedure is valid.
Does anyone have any ideas why my comments could have caused compilation to fail but his comments do not?
I guess it was an unsubtle way to change my comment format to his comment format, wrapped in "error" context.
The answer is most likely plain and simple: Your colleague used a tool that does not handle comments well. Some reporting tools do not handle these types of things at all.
Related
Can anybody explain to me, why this syntax is not working at all, when I try to compile it in a SQL Developer worksheet? It seems as the '#' char is kind of preprocessed by th SQL Developer, but I did not find any explanations, why what is happening here.
CREATE OR REPLACE PROCEDURE PROC_TEST
IS
/*
# example
*/
BEGIN
DBMS_OUTPUT.PUT_LINE('Test # Procedure');
END;
/
this works fine:
CREATE OR REPLACE PROCEDURE PROC_TEST
IS
/*
- example
*/
BEGIN
DBMS_OUTPUT.PUT_LINE('Test # Procedure');
END;
/
SQL Developer Version 17.2.0.188
Oracle Database 12c
thanks a lot.
When you say it's not working, can you show the error that SQL Developer is giving you?
It could be a SQL Developer bug. If I try the same code in version 18.3, it compiles just fine.
My procedure looks like this:
Declare
cur_1 Sys_Refcursor;
cur_2 Sys_Refcursor;
v_1 VARCHAR2(30);
v_2 VARCHAR2(30);
v_3 VARCHAR2(30);
v_4 VARCHAR2(30);
Begin
OPEN cur_1 for Select * from tab1#dblink1;
Loop
Fetch cur_1 into v_1, v_2;
EXIT WHEN cur_1%NOTFOUND;
OPEN cur_2 for Select * from tab2#dblink1 where col1 = v_1 and col2 = v2;
Loop
Fetch cur2 into v_3, v_4;
Exit when cur_2%notfound;
INSERT INTO local.tab3 values (v_1,v_2, v_3, v_4);
END Loop;
close cur_2;
End Loop;
close cur_1;
END;
The abobe procedure compiles, but when I run it I get following error:
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
No more data to read from socket
...(Few more 'No more data to read from socket')
IO Error: Connection reset by peer: socket write error
Process exited.
Interesting thing is when I comment out the entire inner loop the procedure runs without error. So I know something is wrong with the inner loop (I tried commenting only the insert statement inside the inner loop and got the same error).
Both my localdb and dblink1 databases have same version:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
Generic advice for troubleshooting "No more data to read from socket" errors.
These errors are usually caused by another serious error, such as an ORA-600 error. A problem so serious that the server process crashed and could not even send a proper error message to the client. (Another common reason for these errors is a network disconnection caused by SQLNET.EXPIRE_TIME or some other process that kills old sessions.)
Look at the Alert Log to find out the original error message.
Look for the file alert_[name].log in this directory: select value from v$parameter where name = 'background_dump_dest';
After you find the specific error message and details, go to support.oracle.com. Use the "ora-600 tool" and then lookup the first number after the ORA-600 message.
There will usually be one or more articles for that specific type of ORA-600 error. Use the exact version and platform to narrow down the possible list of bugs. (But don't be surprised if the "Versions affected" in the article are wrong. Oracle's claims of "fixed in version x.y" are not always true.)
The articles typically explain in more details how the problem happened, possible workarounds, and a solution that usually involves a patch or upgrade.
In practice you rarely want to solve these problems. The "typical" advice is to contact Oracle Support to verify you really have the same problem, get a patch, get permission and bring down the environment(s), and then apply the patch. And then probably realize the patch doesn't work. Congratulations, you just wasted a lot of time.
Instead, you can usually avoid the problem with a subtle change to the query or procedure. There are a lot of features in Oracle, there's almost always another way to do it. If the code ends up looking a bit weird, add a comment to warn future programmers: "This code looks weird to avoid bug X, which should be fixed in version Y."
Specific advice for this code
If that's really your entire procedure, you should replace it with something like this:
insert into local.tab3(col1, col2, col3, col4)
select tab1.col1, tab1.col2, tab2.col1, tab2.col2
from tab1#dblink1 tab1
join tab2#dblink1 tab2
on tab1.col1 = tab2.col1
and tab1.col2 = tab2.col2;
In general, you should always do things in SQL if possible. Especially if you can avoid opening many cursors. And especially if you can avoid opening many cursors to a remote database.
As jonearles mentioned you should write this in one SQL statement.
If you insist on using PL/SQL : you are doing way too much work yourself, declaring variables, open cursors, looping, assigning variables. Consider this PL/SQL:
begin
for c1 in (select * from tab1#dblink1)
loop
for c2 in (Select * from tab2#dblink1 where col1 = c1.col1 and col2 = c1.col2)
loop
insert into local.tab3 values (c1.col1,c1.col2,c2.col1,c2.col2);
end loop;
end loop;
end;
/
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. :)
I am using oracle 10g express edition. It has a nice ui for db developers. But i am facing some problems executing stored procedures.
Procedure:
create or replace procedure temp_proc is
begin
DBMS_OUTPUT.PUT_LINE('Test');
end
it is created successfully. But when i execute:
execute temp_proc;
it shows ORA-00900: invalid SQL statement
So help needed here
Execute is sql*plus syntax .. try wrapping your call in begin .. end like this:
begin
temp_proc;
end;
(Although Jeffrey says this doesn't work in APEX .. but you're trying to get this to run in SQLDeveloper .. try the 'Run' menu there.)
Oracle 10g Express Edition ships with Oracle Application Express (Apex) built-in. You're running this in its SQL Commands window, which doesn't support SQL*Plus syntax.
That doesn't matter, because (as you have discovered) the BEGIN...END syntax does work in Apex.
Both 'is' and 'as' are valid syntax. Output is disabled by default. Try a procedure that also enables output...
create or replace procedure temp_proc is
begin
DBMS_OUTPUT.ENABLE(1000000);
DBMS_OUTPUT.PUT_LINE('Test');
end;
...and call it in a PLSQL block...
begin
temp_proc;
end;
...as SQL is non-procedural.
I use oracle 12 and it tell me that if you need to invoke the procedure then use call keyword.
In your case it should be:
begin
call temp_proc;
end;
Have you tried to correct the syntax like this?:
create or replace procedure temp_proc AS
begin
DBMS_OUTPUT.PUT_LINE('Test');
end;
In Oracle SQL Developer (GUI), using 12c, also don't forget to enable the DMBS Output window (click View => Dbms Output, then click "+" sign, and select your connection), by default the window is not enabled.
The following syntax will then output to this window:
begin
temp_proc
end;
You can do simply the following on the Command Window:
Connected to Oracle Database 19c Enterprise Edition Release 19.0.0.0.0
Connected as XXX#YYY
SQL> call temp_proc();
Or:
SQL> execute temp_proc();
After some struggle with Oracle Advanced Queuing and dbms_aq package
I encountered another issue. I copied code from Oracle tutorials
but when I compile this code:
create or replace
procedure jms_test(msg varchar2)
is
id pls_integer;
message sys.aq$_jms_stream_message;
enqueue_options dbms_aq.enqueue_options_t;
message_properties dbms_aq.message_properties_t;
begin
message := sys.aq$_jms_stream_message.construct(0);
message.set_string_property('FROM', 'TEST');
id := message.clear_body(-1);
end;
it complains with:
Error(9,40): PLS-00302: component 'CONSTRUCT' must be declared
Error(10,10): PLS-00302: component 'SET_STRING_PROPERTY' must be declared
Error(11,16): PLS-00302: component 'CLEAR_BODY' must be declared
I think this code works out of procedure body, because I tried with success
recipes from What's in my JMS queue?
My Oracle version is:
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
Any idea what can be wrong?
Looks like a database version problem. AQ$_JMS_STREAM_MESSAGE has a construct method in 10G but not in 9i. What version of Oracle Server are you using?
Looks like grants again
GRANT EXECUTE ON SYS.aq$_jms_stream_message To <your-user>;
Does:
desc sys.aq$_jms_stream_message
work in SQL*Plus from both the SYS + your schema?
Note that SYS.AQ$_JMS_STREAM_MESSAGE is a datbase object/type, whereas SYS.DBMS_AQ is a package
EDIT
Ok... maybe the TYPE body is missing / invalid. What does:
SELECT owner, object_name, object_type, status
FROM dba_OBJECTS
WHERE OBJECT_NAME = 'AQ$_JMS_STREAM_MESSAGE'
return?