PL/SQL errors; ORA-00933: SQL command not properly ended - oracle

I'm new to pl/SQL. The error I'm getting is :
ORA-06550: line 3, column 2: PL/SQL: ORA-00933: SQL command not properly ended
ORA-06550: line 2, column 1: PL/SQL: SQL Statement ignored
So far I have tried adding parentheses, but no luck. I know its a syntax error, but I'm not sure where my mistake is. I tested each line , line by line and I believe there is a problem with my if statement. Does anyone know how I can fix the error for the following code?
SELECT CITRIX from SWLR_ASSET where swlr_key = :p26_swlr_id
if CITRIX=1 then --If Citrix installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_CITRIX_LICENSES=TOTAL_CITRIX_LICENSES+1
WHERE SOFTWARE_NAME=select (Software_name||' ,'||software_version) from swlr_software where software_id = (select software from swlrequest where swlr_id = :p26_swlr_id)
else --If manual installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_PHYSICAL_LICENSES=TOTAL_PHYSICAL_LICENSES+1
WHERE SOFTWARE_NAME= select (Software_name||' ,'||software_version) from swlr_software where software_id = (select software from swlrequest where swlr_id = :p26_swlr_id)
end if;

when you want to a write in plsql a block statement you have to include begin and end; and you have to decalre your variables
declare p26_swlr_id number(specify a number);
v_name varchar2(500);
v_name1 varchar2(500);
begin
p26_swlr_id :=33;( or if its from a table select swrl_id into p26_swlr_id from table where something);
-- this to give you the values for your conditions , its not tested though, and from your condition it should return one record.
select (Software_name||' ,'||software_version) into V_name from swlr_software where software_id = (select software from swlrequest where swlr_id = p26_swlr_id)
select (Software_name||' ,'||software_version into V_name1 from swlr_software where software_id = (select software from swlrequest where swlr_id = :p26_swlr_id)
-- you have to put `;` when you end select
SELECT CITRIX from SWLR_ASSET where swlr_key = p26_swlr_id;
if CITRIX=1 then --If Citrix installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_CITRIX_LICENSES=TOTAL_CITRIX_LICENSES+1
WHERE SOFTWARE_NAME=V_name;
else --If manual installation is required
UPDATE SOFTWARE_REPORT_DASHBOARD
SET TOTAL_PHYSICAL_LICENSES=TOTAL_PHYSICAL_LICENSES+1
WHERE SOFTWARE_NAME= V_name2;
end if;
end;
/

Try to declare a variable and then use the select into statement.
SELECT CITRIX into V_CITRIX from SWLR_ASSET where swlr_key...
Then where you compare, use the variable.
if V_CITRIX=1 then
...
And why aren't you using declare/begin/end? From where are you getting the parameters?

Related

Check Package exist or not before create it in Oracle

Need help
How do I check for a package if it exists or not and skip the creation if it already exists.
I have done the following and I got an error
DECLARE
l_cnt INTEGER;
own VARCHAR(200);
BEGIN
SELECT sys_context( 'userenv', 'current_schema' ) INTO own FROM dual;
SELECT count(*)
INTO l_cnt
FROM ALL_OBJECTS
WHERE object_type = 'PACKAGE'
and object_name = 'JUSTICE_LEAGUE'
AND OWNER = own;
IF( l_cnt <= 0) THEN
EXECUTE IMMEDIATE
'create or replace PACKAGE "JUSTICE_LEAGUE" AS
FUNCTION BATMAN(argPSN INT)
RETURN INT;
FUNCTION SUPERMAN(argSN int)
RETURN Info.infovalue%Type;
PROCEDURE AQUAMAN(argASN INT,argAssignedUser folderProcess.assignedUser%Type DEFAULT 'None');
END JUSTICE_LEAGUE';
DBMS_OUTPUT.PUT_LINE('Package created successfully');
ELSE
DBMS_OUTPUT.PUT_LINE('Package exists already');
END IF;
END;
/
Error report -
ORA-06550: line 23, column 70:
PLS-00103: Encountered the symbol "ALL" when expecting one of the following:
Is it a right way to put the create command for package within EXECUTE IMMEDIATE ?
First of all - no, it is wrong way to do that. The fact that dynamic SQL exists doesn't mean that you should use it, especially not for creating packages (or any other objects). There are really rare situations you'd want to do that.
PL/SQL procedures (functions, packages, triggers) offer create OR REPLACE option so - it is safe to run that statement as is (not as dynamic SQL). It means that:
if it doesn't exist, it'll be created
if it exists, it'll be overwritten by code you've just ran
If you insist on dynamic SQL, check its (package's) existence by querying user_objects:
SQL> select count(*)
2 from user_objects
3 where object_name = 'JUSTICE_LEAGUE'
4 and object_type = 'PACKAGE';
COUNT(*)
----------
0
SQL>
Depending on result, run execute immediate (or not).
There is only one issue with your code.
You have not handled the dynamic query properly. single-quote in the dynamic query must be escaped.
Two single quotes('') in the string are considered as one single quote(') in the final string.
Or you can use the quoted-string (q'{<your_string>}')
replace -- DEFAULT 'None'); with DEFAULT ''None'');

How to use a variable in a LIKE clause in PL/SQL

I am new to Oracle and learning; I am simply trying to run this T-SQL query
DECLARE #SearchObj varchar(100);
SET #SearchObj='%aldbrough%';
SELECT
obj_id,
name,
description
FROM
agnis.t_object
WHERE
lower(name) = ObjToSearch ;
I am using SQL Developer Oracle tool which also have a "Scratch Editor" to help with translation from T-SQL. When i run the tool it gave me this code
DECLARE
v_SearchObj VARCHAR2(100);
BEGIN
v_SearchObj := '%aldbrough%' ;
SELECT obj_id ,
NAME ,
DESCRIPTION
FROM agnis.t_object
WHERE LOWER(NAME) = ObjToSearch;
END;
but the same tool give me this error
Error report -
ORA-06550: line 10, column 26:
PL/SQL: ORA-00904: "OBJTOSEARCH": invalid identifier
ORA-06550: line 6, column 4:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
so what is the correct syntax to use a variable into a LIKE clause that returns multiple rows?
I hope I do not have to use cursors etc for such of a simple statement as suggested in this question
Well, yes - those "translators" don't always do what they are supposed to.
This is how your code should look like:
use like, not = in the where clause
in PL/SQL, you have to put the result of the select statement into something - for example, locally declared variables (as my example shows).
So:
DECLARE
v_SearchObj VARCHAR2 (100) := '%aldbrough%';
--
v_obj_id t_object.obj_id%TYPE;
v_name t_object.name%TYPE;
v_description t_object.description%TYPE;
BEGIN
SELECT obj_id, NAME, DESCRIPTION
INTO v_obj_id, v_name, v_description
FROM agnis.t_object
WHERE LOWER (NAME) LIKE v_searchobj;
END;
If such a code returns an error - too_many_rows (and yes, it does), then one option is to loop through rows and do something (such as display those values):
DECLARE
v_SearchObj VARCHAR2 (100) := '%aldbrough%';
BEGIN
FOR cur_r IN (SELECT obj_id, NAME, DESCRIPTION
FROM agnis.t_object
WHERE LOWER (NAME) LIKE v_searchobj)
LOOP
DBMS_OUTPUT.put_line (
'Name = ' || cur_r.name || ', description = ' || cur_r.description);
END LOOP;
END;
Since this is tagged SQL Developer, use a bind variable:
SELECT obj_id,
name,
description
FROM agnis.t_object
WHERE lower(name) = :ObjToSearch;
and SQL developer will pop up a dialog box where you can set the value of the ObjToSearch variable.
If you want to specify the bind variable in code then:
VARIABLE objtosearch VARCHAR2(50)
BEGIN
:objtosearch := '%aldbrough%';
END;
/
SELECT obj_id,
name,
description
FROM agnis.t_object
WHERE lower(name) = :ObjToSearch;
And run the statements as a script using F5 rather than as individual statements.

Oracle PL/SQL SELECT INTO clause thinks it needs another INTO

I have a simple test function where I'm passing in a specific ID (the primary key of the table I'm selecting from), and computing a simple function on it and the parameters.
The skeleton code and test:
create or replace function test(id varchar2, area float) return float is
theRow forest%ROWTYPE;
begin
select * into theRow from forest where Forest_No = id;
return area / theRow.Area;
end;
begin
select test('1', 16000) from dual;
end;
The output:
[2019-10-14 21:19:10] [65000][6550] ORA-06550: line 2, column 5:
[2019-10-14 21:19:10] PLS-00428: an INTO clause is expected in this SELECT statement
I am at a loss for what to do here, as far as I can tell the documentation and examples use the same order and syntax. I have tried moving the into clause to the end as in Postgresql, but that did not work.
What have I missed here?
Issue is in calling statement.
Whenever select statement is used in plsql block it must have into clause to assign return value to variable.
You should remove begin and end from your calling code:
--begin -- remove this
select test('1', 16000) from dual;
--end; -- remove this
Or if you want to use it in plsql block then add into clause:
Declare
Area_ float(precision);
begin
select test('1', 16000) into area_ from dual;
-- use area_ in your code wherever required
dbms_output.put_line('area: ' || area_);
end;
Cheers!!

PLSQL ignore compilation error which is not an error

I came accross interesting error where I am not sure about best way how to fix it. Given following block:
DECLARE
v_column_exists number := 0;
host_column_exists number := 0;
i number;
BEGIN
Select count(*) into v_column_exists from user_tab_cols where column_name = 'CONNECTIONDESCRIPTION' and table_name = 'NODES';
if (v_column_exists = 1) then
Select count(*) into host_column_exists from user_tab_cols where column_name = 'HOST' and table_name = 'NODES';
if (host_column_exists = 0) then
execute immediate 'alter table NODES add (Host varchar2(255))';
for item in (select connectiondescription, code from nodes) loop
... LOOP STUFF ...
end loop;
end if;
end if;
END;
I get following result:
PL/SQL: ORA-00904: "CONNECTIONDESCRIPTION": invalid identifier
ORA-06550: line 40, column 20: PL/SQL: SQL Statement ignored
ORA-06550: line 41, column 20: PLS-00364: loop index variable 'ITEM'
use is invalid
any ideas how to get rid of this error? Problem is occuring when column NODES.CONNECTIONDESCRIPTION is not present in database, however in such case for loop won't execute in runtime. I would need to disable these errors, but haven't found any way to do it. I have tried using ALTER SESSION SET PLSQL_WARNINGS='DISABLE:00904', but it had no effect.
Thanks
Correct approach was to use another dynamic query which bulk collects items to an array and then loop through this array.

How do I convert SQL code to PL/SQL for an APEX process

I've got the below code which works perfectly in SQL Developer, but I need to input the code within a process block in APEX and it is only giving me a PL/SQL option. Below is the code which I've written:
BEGIN
truncate table TEMP_UPLOAD;
Merge into INVOICE b
USING (
SELECT CUSTOMER_CLASS,RULE_AGGREGATOR,BA
FROM CUSTOMER_TEMP_UPLOAD
WHERE CUSTOMER_CLASS = 'CUSTOMER88') u
ON (b.BA = u.BA)
WHEN MATCHED THEN UPDATE SET b.CUSTOMER88_DATE_UPDATED = sysdate
WHEN NOT MATCHED THEN
INSERT (b.CUSTOMER_CLASS,b.RULE_AGGREGATOR,b.BA,b.CUSTOMER88_DATE_ADDED)
VALUES (u.CUSTOMER_CLASS,u.RULE_AGGREGATOR,u.BA,sysdate);
UPDATE INVOICE a
SET a.CUSTOMER88_DATE_REMOVED = sysdate
WHERE BA IN
(select b.BA
from INVOICE b
left join CUSTOMER_temp_upload u
on b.BA = u.BA
where u.BA is null and b.CUSTOMER_CLASS = 'CUSTOMER88');
END;
Getting following error
1 error has occurred
•ORA-06550: line 3, column 14: PLS-00103: Encountered the symbol "TABLE" when expecting one of the following: := . ( # % ;
The error message is pointing you to your TRUNCATE TABLE command.
TRUNCATE is a DDL command - don't call it from PL/SQL. Instead, use a DELETE so that your process will be transaction-safe.
(P.S. it is technically possible to run DDL from PL/SQL using EXECUTE IMMEDIATE - but I don't advise it)
Seems that the issue was it did not like my BEGIN and END; in uppercase. When I changed it to Begin and end; as well as changed the TRUNCATE table command to a delete, it then accepted it and the PL/SQL command worked as intended.

Resources