Oracle PLSQL: different behavior with two different DBs - oracle

I wrote myself a little PL/SQL utility. Executing it (using SQL-Developer) against one DB (an Oracle XE installation on my Windows 10 Laptop) it works perfectly fine, but executing it against an other DB (also Oracle XE but on a Linux server) I am getting compile errors in my script!?!? How can that be?
The errors I get are:
ORA-06550: line 17, column 35:
PLS-00491: numeric literal required
ORA-06550: line 18, column 35:
PLS-00491: numeric literal required
ORA-06550: line 19, column 35:
PLS-00491: numeric literal required
ORA-06550: line 20, column 35:
PLS-00491: numeric literal required
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
The referenced locations are in this section at the begin of my script:
DECLARE
-- limits and boundaries
MAX_NAME_LENGTH CONSTANT NUMBER(3) := 30; -- for table and column names
MAX_VALUE_LENGTH CONSTANT NUMBER(5) := 10000; -- for column values
-- our starting point:
m_owner VARCHAR2(MAX_VALUE_LENGTH) := 'C##TEST';
m_start_table_name VARCHAR2(MAX_NAME_LENGTH) := 'XML_MELDUNG_QUEUE';
m_start_column_name VARCHAR2(MAX_NAME_LENGTH) := 'XML_MELDUNG_ID';
m_start_value VARCHAR2(MAX_VALUE_LENGTH) := '5647';
...
and the exact spot turned out to be the usages of the constants, i.e. the "...(MAX_....)"-clauses.
It seems as if on the second system the CONSTANT-definitions and the usage of these constants in further declarations does not work the same way as it does when targeting my local DB.
I am completely puzzled! What is the problem here? Why would such a PL/SQL declaration work using one Oracle XE DB but not when using another? I mean: I would understand, if some entity can not be found, but compile errors (or not) depending on the DB used???
Any idea or pointer?

Declaring variable lengths using constants is a feature added in Oracle Database 12.2.
So I suspect that your local installation of XE is 18c. And the other is 11.2.
You can verify this by running:
select * from v$version;

Related

Object is invalid PLSQL Procedure

I use a dataset that has billing information:
Table Image
And I want to create a procedure that gives information about a specific bill by giving an invoice id
CREATE OR REPLACE PROCEDURE print_information(
invoiceID varchar(11);
) IS
p_smtable supermarket%ROWTYPE;
BEGIN
SELECT * INTO p_smtable FROM SUPERMARKET
WHERE invoice_id = invoiceID;
DBMS_OUTPUT.PUT_LINE(p_smtable.brancj || p_smtable.city);
END;
The compilation is successful.
Compile
begin
print_information('750-67-8428');
end;
But I get an error that says:
Error starting at line : 12 in command -
begin
print_information('750-67-8428');
end;
Error report -
ORA-06550: line 2, column 1:
PLS-00905: object SYSTEM.PRINT_INFORMATION is invalid
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
The code in the screenshot is different to the version in your question, but both have an error at line 2. The parameter should be varchar2 or supermarket.invoice_id%type, with no semicolon.
Also, we normally use a p_ prefix for parameters, not variables. (There are other conventions, but whatever you use, p_ for a variable is just confusing.)
A fixed version might be:
create or replace procedure print_information
( p_invoice_id supermarket.invoice_id%type )
as
l_market supermarket%rowtype;
begin
select * into l_market
from supermarket
where invoice_id = p_invoice_id;
dbms_output.put_line(l_market.brancj || ' '|| l_market.city);
end;
Whatever tool you are using for development, you need to become familiar with how to display compilation errors.
brancj might be a typo for branch.
I've assumed you want a space between branch and city, otherwise the output would be something like TottenhamLondon rather than Tottenham London.
In Oracle a schema belongs to one user, created with the CREATE USER command. An Oracle Database is the entire thing (all users, all data, storage, memory, processes, everything) so you would not normally create one for something like this.

identifier 'DBMS_CDC_PUBLISH.CREATE_CHANGE_SET' must be declared

I am using oracle 11g express edition and I am getting the below error when trying to create a change set.
Error report -
ORA-06550: line 2, column 3:
PLS-00201: identifier 'DBMS_CDC_PUBLISH.CREATE_CHANGE_SET' must be declared
ORA-06550: line 2, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I know CDC is desupported in later versions of oracle but I think it is supported here.
Can anyone help please/
Thanks in advance!
The problem is that you are using Express Edition, which does not include Change Data Capture functionality.
https://docs.oracle.com/cd/E17781_01/license.112/e18068/toc.htm#XELIC101

Why does this db link chain cause a "looping chain of synonyms" error only within an anonymous block?

I am in a position which requires I pull data to my primary database through a daisy chained dblink set up similar to what is described in this answer
DBLINK_SERVER2 -> SYNONYM -> DBLINK_SERVER3
The synonym is set up on server 2 like this:
CREATE OR REPLACE SYNONYM "MY_USER"."THE_VIEW" FOR "THE_VIEW"#"DBLINK_SERVER3"
When I run a simple select statement from server 1, it works fine and pulls back exactly what i'd expect from server 3's view:
SELECT COUNT(*) FROM THE_VIEW#DBLINK_SERVER2;
However, whenever I try to run code in an anonymous block any reference to the dblink will cause a "looping chain of synonyms" error.
DECLARE
testnum VARCHAR2(50);
BEGIN
SELECT COUNT(*) INTO testnum FROM THE_VIEW#DBLINK_SERVER2;
END;
/
Error report -
ORA-06550: line 2, column 22:
PL/SQL: ORA-01775: looping chain of synonyms
ORA-06550: line 2, column 1:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
There aren't any synonyms on server 1 that i can see which reference the view or dblink. If i run this same test on server 2 both the simple command and block work fine when i use the synonym. Any idea why the block fails on server 1 but not if i run the same thing outside of the block? Is this some kind of permissions problem?
*** Edit ***
We never determined what was causing this, but the DBA changed it so that we were referencing a view in server 2 instead of a symlink. That resolved our problem.
CREATE VIEW THE_VIEW AS SELECT * FROM THE_VEW#DBLINK_SERVER3

Compiling a stored procedure with local functions on Oracle 9i

I have a legacy application that is still running on Oracle 9i. We'll me migrating to 11g later this year, but for the moment, I need to run some test scripts on the current environment.
My test uses a stored procedure, but when I try to compile the procedure I get the following error.
"PLS-00103: Encountered the symbol "end-of-file" when expecting one of
the following:"
This is strange as the stored procedure compiled on the same server about two years ago. The only difference is that the database has been overwritten with a copy of the production database since (this procedure is only used in test, so is not present in the production database).
The problem seems to stem from local functions within the procedure. Here's a very simple procedure that illustrates the error I'm getting:
create or replace procedure test
as
l_dt date;
function dt
return date
is
begin
return sysdate;
end;
begin
l_dt := dt;
dbms_output.put_line(to_char(l_dt, 'dd-mm-yyyy'));
end;
Edit: Here's the complete output when I try to compile this:
1 ORA-24344: success with compilation error
10 PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
10
10 begin function package pragma procedure form
13 ORA-06550: line 2, column 3:
13 PLS-00201: identifier 'L_DT' must be declared
13 ORA-06550: line 2, column 3:
13 PL/SQL: Statement ignored
14 ORA-06550: line 3, column 32:
14 PLS-00201: identifier 'L_DT' must be declared
14 ORA-06550: line 3, column 3:
14 PL/SQL: Statement ignored
14 SQL parse error location
It definitely seems to be the local function that's causing it, as if I take it out, it compiles just fine. Here's the above procedure with the local function removed, and that working:
create or replace procedure test
as
l_dt date;
begin
l_dt := sysdate;
dbms_output.put_line(to_char(l_dt, 'dd-mm-yyyy'));
end;
I wonder if anyone else has encountered this problem, or knows if there's any reason local functions wouldn't compile under Oracle 9i?
Thanks,
James
The error is being reported against line 10, after the end of the function, so the enclosing procedure isn't being parsed properly. What you're doing is fine though, and works through other clients, and with the version of SqlDbx I tried. It looks like the procedure is being treated as two statements, and sent to the database in two chunks, neither of which is valid on its own.
This problem is reported on the SqlDbx Oracle forum, which mentions the bug exists in versions 3.64 and 4.0. It doesn't appear to be specific to the Oracle version. On 2014-04-14 the response was:
This is a bug and it will be fixed in a follow up to the latest release in about two weeks.
The release notes for version 4.1 include:
Fixes:
1. Corrupted text returned in Unicode version
2. Error parsing nested function (Oracle)
...
So you need to upgrade to version 4.1 or later; the current version is 4.3, and I don't see this problem with that version against a 9i or 11g database.

How to make Oracle error messages more verbose?

The message that drives me crazy is ORA-01008 - Not all variables bound.
Is there a way to know which one of the 42 possible variable names I have misspelled without staring at the monitor till my eyes pop out?
Update: I use ADO.NET to access the database. Perhaps it does lose some information in Oracle exceptions, as #Justin Cave has suggested. But I'm positive that the parameter name never appears even in SQL Plus.
In general, Oracle provides the line and column number of any errors, but it is up to the particular API you are using (unless you happen to be writing an OCI application, which is probably unlikely) as to whether and how those APIs are called. Since the answer is likely to end up being API-specific, what API are are you using and what does your code look like when the error occurs (i.e. JDBC, ODBC, OLE DB, etc)?
As an example, if I write a PL/SQL block with a misspelled variable name, SQL*Plus will report the line and column number of the error in addition to the error message. Many APIs, on the other hand, will just report the PLS-00201 error by default.
SQL> declare
2 i integer;
3 begin
4 j := 1;
5 end;
6 /
j := 1;
*
ERROR at line 4:
ORA-06550: line 4, column 3:
PLS-00201: identifier 'J' must be declared
ORA-06550: line 4, column 3:
PL/SQL: Statement ignored
Similarly, if you execute a SQL statement with an invalid variable name, SQL*Plus will get the column and line position and put a * under the offending character, i.e.
SQL> create table a( col1 number );
Table created.
SQL> insert into a( colN ) values ( 1 );
insert into a( colN ) values ( 1 )
*
ERROR at line 1:
ORA-00904: "COLN": invalid identifier
Most PL/SQL IDE's (TOAD, SQL Developer, etc.) will do something similar by interrogating the appropriate OCI APIs under the covers. Precisely how this is done, however, will depend on the API.
I don't know of any way to get Oracle to make the error more specific. Maybe some future version will improve this error message.
Instead of just staring at it, though, there are other things you can try. For example, convert each variable in the SQL statement to a literal one at a time, until the error goes away. If possible, generate the list of variable names instead of typing them manually.

Resources