In Oracle PLSQL, how to declare IN parameter as NUMBER(9,2)? - sql

I want to declare amount parameter as type NUMBER(9,2); How come this Oracle PL/SQL procedure doesn't work?
CREATE OR REPLACE PROCEDURE spupdate_price_by_cat(amount IN NUMBER(9, 2))AS
BEGIN
END;
/
When I run it, i get error:
Encountered the symbol "(" when expecting one of the following: := . ) , # % default character. The symbol ":=" was substituted for "(" to continue.

You cannot declare a NUMBER data type with scale and precision in the signature of a PL/SQL function or procedure.
Either use NUMBER:
CREATE OR REPLACE PROCEDURE spupdate_price_by_cat(
amount IN NUMBER
)
AS
BEGIN
NULL;
END;
/
Or use a %TYPE declaration to declare it to have the same data type as a column of a table (but it still does not respect the column's scale and precision in the signature):
CREATE OR REPLACE PROCEDURE spupdate_price_by_cat(
amount IN table_name.column_name%TYPE
)
AS
BEGIN
NULL;
END;
/
If you want a particular scale and precision enforcing in a PL/SQL variable then declare it locally in the procedure:
CREATE OR REPLACE PROCEDURE spupdate_price_by_cat(
amount IN table_name.column_name%TYPE
)
AS
v_amount1 NUMBER(9,2) := amount;
v_amount2 table_name.column_name%TYPE := amount;
BEGIN
DBMS_OUTPUT.PUT_LINE(v_amount1);
END;
/
db<>fiddle here

Related

Error "Encountered the symbol "IN" when expecting one of the following" in Oracle

This is the code:
CREATE PROCEDURE print_string(IN input_string VARCHAR(255))
BEGIN
DECLARE num_chars INT DEFAULT 0;
IF input_string IS NULL THEN
SET num_chars = 0;
ELSE
SET num_chars = CHAR_LENGTH(input_string);
END IF;
SELECT UPPER(input_string), num_chars;
END;
I get error:
PLS-00103: Encountered the symbol "IN" when expecting one of the following: <an identifier> <a double-quoted delimited-identifier>
current delete exists prior
Errors: check compiler log
How do I fix: current delete exists prior?
The immediate error is that you have the argument name and mode the wrong way around - it should be (input_string IN ... not (IN input_string .... But there are other problems:
Oracle recommends VARCHAR2 over VARCHAR.
arguments just have the data type, not a size (or precision/scale), so it should be (input_string IN VARCHAR2) not (input_string IN VARCHAR2(255).
you are missing the IS/AS keyword.
DECLARE comes before BEGIN in a PL/SQL block; having a nested block here would be valid, but you're missing a BEGIN and END; if you do that, and it isn't necessary so I don't think it's what you meant. And you don't need the DECLARE at all for a procedure, it's implied.
if you want a default value for a PL/SQL variable then assign it, rather than using DEFAULT. (You don't really need to do this here, as you always assign a value later anyway, but I'm sticking with your general approach.)
it's probably better to use native Oracle types, so NUMBER or PLS_INTEGER instead of INT.
assignment of values is with :=, not SET ... = ....
CHAR_LENGTH should just be LENGTH (unless you have your own function with that name).
in PL/SQL you have to select into something, and from something. But if you do that here, you still have to return it to the caller somehow.
given that you want to 'print' the string, you probably want dbms_output - though that relies on the client showing the result, which most don't by default, and it's generally only used for debugging...
So this would work:
CREATE PROCEDURE print_string(input_string IN VARCHAR2) AS
num_chars PLS_INTEGER := 0;
BEGIN
IF input_string IS NULL THEN
num_chars := 0;
ELSE
num_chars := LENGTH(input_string);
END IF;
DBMS_OUTPUT.PUT_LINE(UPPER(input_string) || ': ' || num_chars);
END;
/
BEGIN
DBMS_OUTPUT.ENABLE;
print_string('This is a test');
END;
/
1 rows affected
dbms_output:
THIS IS A TEST: 14
fiddle
But again, dbms_output isn't ideal. And it could be done much more simply (#Mto has shown one way), or without using PL/SQL at all.
You can fix the issues (listing in #Alex Poole's answer) and simplify the procedure to:
CREATE PROCEDURE print_string(
input_string IN VARCHAR2
)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE(UPPER(input_string) || ', ' || COALESCE(LENGTH(input_string), 0));
END;
/
Then:
BEGIN
DBMS_OUTPUT.ENABLE;
print_string('This is a test');
print_string(NULL);
END;
/
Outputs:
THIS IS A TEST, 14
, 0
fiddle
The code syntax is incorrect here. It should be something like
CREATE OR REPLACE PROCEDURE print_string(input_string IN VARCHAR2)
IS
BEGIN

procedure using loop in oracle

I used oracle
I want to declare a procedure that allows me to make insertion in a table
I try with this code without success
CREATE OR REPLACE PROCEDURE ADDSTEP(nbrStep character varying)
is
i integer :=0;
BEGIN
FOR i IN 0..nbrStep LOOP
INSERT INTO mytabletest
VALUES (i);
END LOOP;
END;
I have this error :
PROCEDURE ADDSTEP compiled
Errors: check compiler log
There are multiple issues with your code:
nbrStep character varying
There is no such data type called "character varying" in Oracle. For string you would use VARCHAR2. However, since you want to use it later in the loop for iteration, you need it to be NUMBER.
FOR i IN 0..nbrStep LOOP
You need to iterate from 1 till the boundary.
i integer :=0;
Not needed.
Modify the procedure as:
CREATE OR REPLACE PROCEDURE ADDSTEP(nbrStep NUMBER)
is
i integer :=0;
BEGIN
FOR i IN 0..nbrStep LOOP
INSERT INTO mytabletest
VALUES (i);
END LOOP;
END;
/
Anyway, you entire procedure could be done in a single INSERT SQL. It is called row generator method.
Try,
INSERT INTO mytabletest
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 100;
Above, in place of 100, you could use the value of your choice which is the value you are passing as parameter **nbrStep ** in the above procedure.
Strange syntax of input variables. Corrected for Oracle -
CREATE OR REPLACE PROCEDURE addstep(nbrstep IN NUMBER)
IS
BEGIN
FOR i IN 0.. nbrstep
LOOP
INSERT INTO mytabletest
VALUES (i);
END LOOP;
END;

Error when calling Oracle stored procedure

Normally i don't work with Oracle DB, but today i had to write a small stored procedure that returns a GUID. (Data Type RAW according to Oracle)
This is what i have created. I can compile the stored procedure, but when i execute it, i get the following error: String length constraints must be in range (1 .. 32767).
CREATE OR REPLACE PROCEDURE GetId (MyInputVar IN VARCHAR2, Guid OUT RAW)
AS
BEGIN
SELECT "unid" into Guid FROM MyDB."incident" WHERE "ExternalId" = GetId.MyInputVar;
END;
DECLARE GiveMeTheGuid RAW;
OtherSystemOrderId VARCHAR2 (60 CHAR) := 'ORDERNR1000';
BEGIN
Sitefinity_Order_NR(OtherSystemOrderId, GiveMeTheGuid);
DBMS_OUTPUT.PUT_LINE(GiveMeTheGuid);
END;
The RAW variable declaration needs a size.
DECLARE
theID RAW(32);
OtherSystemOrderId VARCHAR2 (60 CHAR) := 'ORDERNR1000';
BEGIN
GetID(OtherSystemOrderId, theID);
dbms_output.put_line('unid is ' || theID);
END;
anonymous block completed
unid is 3F66DF77FC234C7B887A18F33C174A6A

(Oracle SQL Stored Proc) Insert a single character into a table -- Value too large for columns

As far as I've read, in declaring a stored procedure it is not possible to specify the length of a CHAR, and so it appears to default to 200 characters in length. This is a problem because my table only accepts a CHAR with 1 character.
So even though I'm only passing in a single character to the stored procedure, I still get this error:
ORA-12899: value too large for columns ... (actual: 200, maximum: 1)
Here's what I have:
CREATE OR REPLACE
PACKAGE BODY TESTPACKAGE AS
PROCEDURE Testing(myChar IN CHAR)
IS
BEGIN
UPDATE my_table SET my_column = myChar WHERE [some condition];
END Testing;
END TESTPACKAGE;
My package declaration:
PROCEDURE Testing(myChar IN CHAR);
The real stored procedure obviously has more parameters and logic, but I've stripped it down to the problem area.
What's the best way to deal with this problem, without resorting to altering my table to accept CHARS with 200 characters (which would be totally unnecessary)?
Thanks
I can only generate this error is the variable being passed in is defined as char(200):
declare
val char(200);
begin
val := 'b';
testpackage.testing(val);
end;
/
ORA-12899: value too large for column ... (actual: 200, maximum: 1)
If val is declared as char(1) or a string literal is passed then it doesn't error:
declare
val char(1);
begin
val := 'b';
testpackage.testing(val);
end;
/
anonymous block completed
begin
testpackage.testing('b');
end;
/
anonymous block completed
So it doesn't appear to default at all. If you can't change how the passed variable is declared, you can trim it:
PROCEDURE Testing(myChar IN CHAR)
IS
BEGIN
UPDATE my_table SET my_column = trim(myChar)
WHERE [some condition];
END Testing;
Then this works:
declare
val char(200);
begin
val := 'b';
testpackage.testing(val);
end;
/
anonymous block completed
This will still fail if the caller tries to pass more than one character, but that's probably what you want.

How do I CAST a NUMBER to VARCHAR2 in Oracle?

I have a problem with some P-SQL syntax. I have reduced the code sample to its minimum below.
The following works:
CREATE OR REPLACE FUNCTION MyFunction(LINE_ID SMALLINT)
RETURN VARCHAR2 IS
tmp VARCHAR2(4000);
BEGIN
tmp := CAST(LINE_ID AS VARCHAR2);
RETURN(tmp);
END MyFunction;
/
However, I need to change the LINE_ID parameter to NUMBER(5, 0), after which the following does not work:
CREATE OR REPLACE FUNCTION MyFunction2(LINE_ID NUMBER(5, 0))
RETURN VARCHAR2 IS
tmp VARCHAR2(4000);
BEGIN
tmp := CAST(LINE_ID AS VARCHAR2);
RETURN(tmp);
END MyFunction2;
/
The error message in Oracle SQL Developer 3.2.10.09 is
Error(1,36): PLS-00103: Encountered the symbol "(" when expecting one
of the following: := . ) , # % default character The symbol ":="
was substituted for "(" to continue.
How should I write the CAST statement in order to make it work with NUMBER(5, 0) instead of SMALLINT?
Again, this is not the original code but I am looking for a solution that does not deviate too much from the second version and preferably not another function call either. The VARCHAR2 return type is important as well.
The function you're looking for is TO_CHAR:
tmp := TO_CHAR(LINE_ID);
You can't specify NUMBER precision and scale for a function's parameter. Just declare it like this:
CREATE OR REPLACE FUNCTION MyFunction2(LINE_ID NUMBER)
The issue is not in your CAST, but rather in your parameter definition. From the documentation:
You can declare a formal parameter of a constrained subtype, like this:
DECLARE
SUBTYPE n1 IS NUMBER(1);
SUBTYPE v1 IS VARCHAR2(1);
PROCEDURE p (n n1, v v1) IS ...
But you cannot include a constraint in a formal parameter declaration, like this:
DECLARE
PROCEDURE p (n NUMBER(1), v VARCHAR2(1)) IS ...