PLS-00103: Encountered the symbol "&" when expecting one of the following - sql

PLS-00103: Encountered the symbol "&" when expecting one of the following...
code:
Declare
num number;
Begin
num := #
if num > 0 then
dbms_output.put_line(‘Hello’);
end if;
end;
/
I'm not sure why I'm getting this message when I'm not seeing anything wrong.

Oracle Live SQL is a tool for trying out SQL and PL/SQL but it doesn't support substitution variable syntax (&var.).
Instead, you can create tables, populate them with data, then run SQL or PL/SQL using them, e.g.:
create table inputs (num number);
insert into inputs values (10);
Declare
num number;
Begin
select num into num from inputs;
if num > 0 then
dbms_output.put_line('Hello');
end if;
end;
/
(p.s. I had to fix the quotes around 'Hello' for this to work)

Oracle live does not support & for get value.
Instead you can initialize the Variable
Declare
num number := 10;
Begin
if num > 0 then
dbms_output.put_line(‘Hello’);
end if;
end;
/

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

SQL I don't understand what is wrong with my trigger

I'm having a hard time understanding this error:
Error at line 3: PLS-00103: Encountered the symbol "&" when expecting one of the following:
) , * & - + / at mod remainder rem and or
as || multiset
CREATE OR REPLACE TRIGGER class_trigger
BEFORE INSERT ON Class FOR EACH ROW
BEGIN
IF (type = 'vl' && mass < 15000) THEN
mass := 15000;
The code is:
CREATE OR REPLACE TRIGGER class_trigger
BEFORE INSERT ON Class FOR EACH ROW
BEGIN
IF (type = 'vl' && mass < 15000) THEN
mass := 15000;
END IF;
END;
What is wrong with my code? I'm using Oracle's APEX. Thanks.
You have two problems:
PL/SQL uses AND as the logical operator for the boolean AND operation, not &&.
When accessing fields which are passed to the trigger, you must qualify them with the :OLD or :NEW pseudo-row names.
Thus, you'd need to rewrite your trigger as:
CREATE OR REPLACE TRIGGER class_trigger
BEFORE INSERT ON Class
FOR EACH ROW
BEGIN
IF :NEW.TYPE = 'vl' AND
:NEW.mass < 15000
THEN
:NEW.MASS := 15000;
END IF;
END class_trigger;

ORA-00917: Missing Comma in PLSQL

I have written a PL SQL script to add values stored in an array into a temp table. I have used Execute immediate to execute the insert query inside a loop.
I have checked the number of single quotes and the number of commas and they are closed. Still, I'm getting the error code
ORA-00917: missing comma.
declare
type post_CODS IS VARRAY(34) OF VARCHAR2(20);
type locality_ID IS VARRAY(34) OF NUMBER(9);
pc post_CODS;
Y varchar2(1);
lid locality_ID;
total integer;
begin
Y := 'Y';
lid := locality_ID(2380,3785,8710,17895,20345,24630,26814,28525,29130,31025,31265,32445,36940,40590,54290,83775,83780,83785,83790,83795,88483,93480,94560,96670,1000524,1000628,1000738,1000857,1000988,1001103,1001466,1001575,1001707,1001744);
pc := post_CODS(2822,2739,2822,2372,2817,4314,4300,4726,4300,4884,4314,4314,4300,5719,3026,4314,4314,4314,4314,4314,873,2582,2817,4314,5723,5440,2083,2575,873,2372,5440,5440,5715,5440);
total := lid.count;
FOR i in 1 .. total LOOP
execute immediate 'insert into tmp_ref_lc_pc_cods values('||lid(i)||','||pc(i)||','||Y||',89987,'||sysdate||')';
END LOOP;
END;
This is the error I am getting
Error report:
ORA-00917: missing comma
ORA-06512: at line 14
00917. 00000 - "missing comma"
I'm working on an oracle machine.
Wrap your insert statement in q'[]' and try
execute immediate q'[insert into tmp_ref_lc_pc_cods values('||lid(i)||','||pc(i)||','||Y||',89987,'||sysdate||')]';
Update
It is recommended to use bind variable. You can try the below. It is working for me and inserting the data.
declare
type post_CODS IS VARRAY(34) OF NUMBER(20);
type locality_ID IS VARRAY(34) OF NUMBER(9);
pc post_CODS;
Y varchar2(1);
lid locality_ID;
total integer;
begin
Y := 'Y';
lid := locality_ID(2380,3785,8710,17895,20345,24630,26814,28525,29130,31025,31265,32445,36940,40590,54290,83775,83780,83785,83790,83795,88483,93480,94560,96670,1000524,1000628,1000738,1000857,1000988,1001103,1001466,1001575,1001707,1001744);
pc := post_CODS(2822,2739,2822,2372,2817,4314,4300,4726,4300,4884,4314,4314,4300,5719,3026,4314,4314,4314,4314,4314,873,2582,2817,4314,5723,5440,2083,2575,873,2372,5440,5440,5715,5440);
total := lid.count;
FOR i in 1 .. total LOOP
execute immediate q'[insert into tmp_ref_lc_pc_cods values(:var1,:var2,'Y',89987,sysdate)]' using lid(i),pc(i);
END LOOP;
END;
A good trick when trying to execute immediate is making sure that the statements created are formatted correctly, printing the code you've written reveals that the Y is not inside of apostrophes
insert into tmp_ref_lc_pc_cods values(2380,2822,Y,89987,23-APR-19)
So when dynamically creating code make sure that all strings created have the right amount of apostrophes.
dbms_output.put_line('insert into tmp_ref_lc_pc_cods values('||lid(i)||','||pc(i)||','''||Y||''',89987,'||sysdate||')');

HANA SQL function to split a comma delimited string into substrings

I have the following HANA Procedure:
CREATE PROCEDURE SP_LIT()
AS
BEGIN
DECLARE count INT;
DECLARE pos INT;
DECLARE value NVARCHAR(100);
value := 'R,A';
IF LENGTH(:value) > 0 THEN
value := :value + ',';
pos := LOCATE(:value,',',1);
END IF;
WHILE :pos > 0 DO
BEGIN
INSERT INTO [O/P table] VALUES (LEFT(:value,:pos-1));
value := RIGHT(:value, LENGTH (:value)-:pos);
pos := LOCATE(:value,',',1);
END;
END WHILE;
END;
Everything seems fine but on execution the following error is thrown:
Error: invalid number exception: invalid number: not a valid number string 'R,A'
Any idea where am I going wrong?
I found the solution.
The '+' sign in concatenation should be replaced by '||' pipe operator.

PL/SQL Error PLS-00103 - Encountered symbol xxxx when expecting yyyy

I know these errors are most often caused by typos; that's what I've been finding at least. If my problem is a typo, I cannot see it after ~30 minutes of looking, it's driving me crazy.
My question is: am I doing something fundamentally wrong, or can you see a typo?
PL/SQL:
CREATE OR REPLACE PROCEDURE Replenish_Stock(p_id VARCHAR2, n INT)
AS
no_such_id EXCEPTION;
CURSOR pc IS
SELECT Product_ID FROM Products;
BEGIN
IF p_id IN pc THEN
UPDATE Products
SET Stock_Level = Stock_Level + n
WHERE product_id = p_id;
ELSE
RAISE no_such_id;
END IF;
EXCEPTION
WHEN INVALID_NUMBER THEN
DBMS_OUTPUT.PUT_LINE('Bad integer input, ignoring procedure call.');
WHEN no_such_id THEN
DBMS_OUTPUT.PUT_LINE('Bad Product id, ignoring procedure call.');
END;
/
Error code:
Error(7,14): PLS-00103: Encountered the symbol "PC" when expecting one of the following: (
Thanks for any help.
Your usage of IN and CURSOR is not right. the below should work for you. You can just use SQL%ROWCOUNT to see if the update query impact any rows in the table.
CREATE OR REPLACE PROCEDURE Replenish_Stock(p_id VARCHAR2, n INT)
AS
no_such_id EXCEPTION;
Rows_Updated NUMBER;
BEGIN
UPDATE Products
SET Stock_Level = Stock_Level + n
WHERE product_id = p_id;
IF( SQL%ROWCOUNT = 0) THEN
RAISE no_such_id;
END IF;
EXCEPTION
WHEN INVALID_NUMBER THEN
DBMS_OUTPUT.PUT_LINE('Bad integer input, ignoring procedure call.');
WHEN no_such_id THEN
DBMS_OUTPUT.PUT_LINE('Bad Product id, ignoring procedure call.');
END;
/