This question already has an answer here:
PLS-00201: identifier 'USER INPUT' must be declared
(1 answer)
Closed 10 months ago.
Why do I get this error? If the variable declaration is the same type as the column shouldn't this work. The nursing_unit_id is a varchar2(10). It worked like this for me when the ID was a NUMBER;
Error I get:
Error report -
ORA-06550: line 13, column 13:
PLS-00201: identifier 'ISS' must be declared
SET SERVEROUTPUT ON;
DECLARE
v_unit ADMISSIONS.NURSING_UNIT_ID%TYPE := &v_unit;
v_admissions ADMISSIONS%ROWTYPE;
CURSOR c_admissions IS
SELECT *
INTO v_admissions
FROM ADMISSIONS
WHERE NURSING_UNIT_ID = v_unit;
BEGIN
FOR r_admissions IN c_admissions
LOOP
DBMS_OUTPUT.PUT_LINE(r_admissions );
END LOOP;
END;
If nursing_unit_id is varchar2(10) and you've defined the substitution variable &v_unit as ISS, then you have to enclose the reference to the substitution variable in quotes, to make it a string:
v_unit ADMISSIONS.NURSING_UNIT_ID%TYPE := '&v_unit';
If you run your code in SQL*Plus or SQL Developer with set verify on, you'll see the before and after values for that substitution, which would show it it trying to to do:
v_unit ADMISSIONS.NURSING_UNIT_ID%TYPE := ISS;
instead of what you'd get with it quoted:
v_unit ADMISSIONS.NURSING_UNIT_ID%TYPE := 'ISS';
You will still get other errors; the next one is:
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
You've defined v_admissions as a row type, which means it's a record. You can't write a whole record out in one go with dbms_output, you have to refer to each field separately, e.g. (using your amended code, where `r_admissions is also implicitly of that same row type):
DBMS_OUTPUT.PUT_LINE(r_admissions.nursing_unit_id);
Having an into clause in the cursor definition isn't useful; it isn't actually populated, so you can remove that clause and the v_admissions variable declaration. You don't really need the v_unit local variable either, you can use the substitution variable directly; and there are various cursor forms you can use, such as:
SET SERVEROUTPUT ON;
BEGIN
FOR r_admissions IN (
SELECT *
FROM ADMISSIONS
WHERE NURSING_UNIT_ID = '&v_unit'
)
LOOP
DBMS_OUTPUT.PUT_LINE(r_admissions.nursing_unit_id);
-- and anything else you want to do with that row's data
END LOOP;
END;
/
Related
create or replace procedure test(supplierid in number,
supplier out varchar) is
begin
select first_name
into Supplier
from lup_sup_master
where sup_id = supplierid;
end;
/
execute test(2279, :supplierid);
or
begin
execute test(2279, :supplierid); dbms_output.enable; dbms_output.put_line(supplier);
end;
Your procedure test has 2 input arguments. One has type IN which is supposed to be used with the procedure and the other parameter supplier has type OUT which means this parameter is suppose to hold the value which the Procedure returns.
As explained by #Barbaros, if you want to execute the Procedure via a SQL command prompt, you can follow the steps.
However the second way you showed was using a PLSQL Block.
begin
execute test(2279, :supplierid);
dbms_output.enable;
dbms_output.put_line(supplier); end;
In the above example of calling, you must note that Execute keyword is only be used whenever you use a SQL command line prompt. While using a PLSQL block you cal directly call the Procedure by its name as shown below. Also note that incase you have a OUT parameter, you must have OUT parameter passed to the Procedure since the Procedure is expecting 2 arguments. See below demo.
declare
var varchar2(100);
begin
test( supplierid => 2279, supplier =>var);
dbms_output.enable;
dbms_output.put_line(var);
End;
It seems you're confused between supplierid and supplier. You need to define a variable for supplier to get an output line printed, and most probably you defined a command line variable supplierid which's numeric type.
So, use below :
SQL> set serveroutput on;
SQL> var supplier varchar2;
SQL> execute test(2279, :supplier);
supplier
---------
Afzal -- as an example name
I have simple plsql program, basically what I would like to do is to calculate the length of the name which is dynamic input to plsql and then loop based on the length.
When I give pre-defined value like v_name = 'Dex' it works but when I give v_name = &name it throws an error message saying Dex must be declared.
Appreciate if any one can shed light on this issue. Please find error and program details below:
Error report:
ORA-06550: line 6, column 13:
PLS-00201: identifier 'DEX' must be declared
ORA-06550: line 6, column 3:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
PLsql Program:
declare
v_name varchar2(30);
v_loop_count number;
v_len number;
begin
v_name := &name;
v_loop_count := 0;
v_len := length(v_name);
for v_loop_count in 0 .. v_len-1
loop
dbms_output.put_line('Entered Name is :: '||v_name);
end loop;
end;
In SQL Developer (and in sqlplus), you can define substitution variables such as you're doing that start with &. But these substitution variables are unlike variables or literals in your code. These substitution variables will only be replaced textually, before the code gets parsed and executed.
If you have
v_name := &name;
Then the textual replacement will yield this code:
v_name := Dex;
Because you don't have a variable named DEX, you get the error you mentioned.
As mentioned in the comments, placing single-quotes around the substitution variable is the answer.
v_name := '&name';
This will get replaced with
v_name := 'Dex';
which is what you wanted -- the string value 'Dex'.
I'm stuck with some simple procedure and I can't figure out why.
This is my code, which I'm running in sqlplus:
CREATE OR REPLACE PROCEDURE NormalizeName(fullname IN NVARCHAR2)
IS
BEGIN
SELECT TRIM(fullname) INTO fullname FROM DUAL;
DBMS_OUTPUT.PUT_LINE(fullname);
END NormalizeName;
/
BEGIN
NormalizeName('Alice Wonderland ');
END;
/
When I run it, I get the error:
Warning: Procedure created with compilation errors.
NormalizeName('Alice Wonderland ');
*
ERROR at line 2:
ORA-06550: line 2, column 2:
PLS-00905: object SYSTEM.NORMALIZENAME is invalid
ORA-06550: line 2, column 2:
PL/SQL: Statement ignored
What's wrong?
1) Never create objects in the SYS or SYSTEM schema. Those are reserved for Oracle. If you want to create objects, create a new schema first.
2) When you see that a procedure has been created with compilation errors in SQL*Plus, type show errors to see the errors.
3) The error appears to be that your SELECT statement is trying to write to the fullname parameter. But that parameter is defined as an IN parameter, not IN OUT, so it is read-only. If you define the parameter as IN OUT, though, you could not pass a string constant to the procedure, you'd need to define a local variable in your calling block. It doesn't make a lot of sense to have a procedure that doesn't do anything other than call dbms_output since there is no guarantee that anyone will see the data written to that buffer. My guess is that you really want a function that returns a normalized name. Something like
CREATE OR REPLACE FUNCTION NormalizeName( p_full_name IN VARCHAR2 )
RETURN VARCHAR2
IS
BEGIN
RETURN TRIM( p_full_name );
END;
which you can then call
DECLARE
l_normalized_name VARCHAR2(100);
BEGIN
l_normalized_name := NormalizeName( 'Alice Wonderland ' );
dbms_output.put_line( l_normalized_name );
END;
If you really need a procedure because this is a homework assignment
CREATE OR REPLACE PROCEDURE NormalizeName( p_fullname IN VARCHAR2 )
AS
BEGIN
dbms_output.put_line( TRIM( p_fullname ));
END;
In the real world, you should only be using procedures when you want to manipulate the state of the database (i.e. you're doing INSERT, UPDATE, DELETE, MERGE, etc.). You use functions when you want to perform calculations without changing the state of the database or when you want to manipulate data passed in parameters.
Im very beginner in psql and i have a question.
Here is the code:
SET serveroutput ON
ACCEPT myVariable PROMPT "Input value: ";
BEGIN
dbms_output.put_line('My input variable is: '||&myVariable);
END;
Question is very simple: How can i pass text to my variable? If i input a number it is works correctly and i can read in the log my number, but if i pass a text like "mytext" instead of a number, i got an error:
old:BEGIN
dbms_output.put_line('My input variable is: '||&myVariable);
END;
new:BEGIN
dbms_output.put_line('My input variable is: '||mytext);
END;
Error starting at line 5 in command:
BEGIN
dbms_output.put_line('My input variable is: '||&myVariable);
END;
Error report:
ORA-06550: 2 sor, 50 oszlop:
PLS-00201: identifier 'MYTEXT' must be declared
ORA-06550: 2 sor, 3 oszlop:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
You have to specify the data type as part of the ACCEPT statement. If none is given, it assumes a number.
Try ACCEPT myVariable CHAR PROMPT 'Input value: '; instead.
You have to enclose the character substitution variable in quotes when you use it, if it's a string, otherwise Oracle tries to interpret the value as an object name. You can see that on the 'new' version (shown because you have set verify on), and sexta13 alluded to that too. So you would do:
dbms_output.put_line('My input variable is: '||'&myVariable');
But you don't need to concatenate the value in this case (whether it's a number or s string):
dbms_output.put_line('My input variable is: &myVariable');
You don't have MYTEXT variable declared anywhere.
dbms_output.put_line('My input variable is: '||mytext); -- here is the error. It should be &myVariable.
Here's the code... this isn't the complete code. I trimmed it down to where the first error occurred:
FUNCTION get (
p_sql_o OUT VARCHAR2
) RETURN VARCHAR2 AS
str_sql VARCHAR2(4000);
BEGIN
str_sql := ' SELECT * FROM ( SELECT A.*, ROWNUM RNUM FROM ( ' ||
' SELECT item_code, ' ||
' item_desc, ' ||
' monitor, ' ||
' measured, ' ||
' inventory, ' ||
' (measured - inventory) adj_amount, ' ||
' (inventory_cost * measured) measured_cost, ' ||
'inventory';
RETURN str_sql;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END get;
Obviously, the SQL is incomplete, but I'm not running it. I'm simply returning the SQL string, yet I still get an error:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 6
This is baffling. Does anyone have any clue as to why this would be the case?
Since you've said you aren't attempting to dynamically execute the SQL you're creating, the syntax and correctness of what's in there, or the length of what it might return, is clearly irrelevant. You aren't doing anything with your p_sql_o OUT parameter, so that isn't causing this problem either. That only really leaves str_sql as the culprit, and as Justin implied yesterday, it's declared as large enough within the function and the function itself compiles OK - so it looks like it has to be how it's being called that's the problem.
You mentioned it works if you remove the 'inventory', which reduced the length of that string from 201 to 192 characters, so I'm guessing you've got this set to 200 chars in the caller, something like:
declare
str_sql varchar2(200);
p_sql_o varchar2(4000);
begin
str_sql := get(p_sql_o);
end;
/
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 5
Note that the line number this is reporting is 5, not 6 as you had; it's the line in the caller that has the error, not the line the assignment happens inside the function. If I make it str_sql varchar2(250); in the caller declaration then it works (but it might as well be 4000 to match the declaration in the function).
declare
str_sql varchar2(250);
p_sql_o varchar2(4000);
begin
str_sql := get(p_sql_o);
end;
/
PL/SQL procedure successfully completed.
But p_sql_o will still be empty because you never set it. It looks like the OUT parameter is redundant. Perhaps you meant to put the SQL string into that instead, and that is already declared as big enough in the caller; but then it isn't clear what the return value would be - you probably just want to remove the OUT parameter completely, and make sure the variable in the caller that you're putting the return value into is large enough.
Have you tried just running the SQL script against the DB outside of the SP? This will help to determine if the sql syntax is correct and that you are returning what is expected. It looks like you expect to get a response that is 4000 bytes or smaller. Are you sure that is what is being returned? I don't see Where clause. Maybe you are returning multiple rows that exceed your limit? Admittedly, I'm not as familiar with stored procedures, so I could be off.
Here you are using p_sql_o as out parameter and not assigning any value inside your function.
So p_sql_o will hold the value it had previously in the code follows after calling line of this function.
As you defined str_sql can hold only 4000 char, if your concatenated string is going beyond that limit it will give character string buffer too small ORA-06512 error.
When you are concatenating the string to create a select statement, check if you are using the single quotes properly or you are missing them at all. If this is happening then while executing the dynamic select statement you may get this error ORA-06502: PL/SQL: numeric or value error: