This question already has an answer here:
oracle sql if condition then select statement1 else select statement2
(1 answer)
Closed 3 years ago.
I tried to execute the plsql IF statement based on the condition. But it does not work.
declare
admin varchar2(4000);
user1 varchar2(4000);
begin
Admin := q'~
SELECT * INTO ADMIN FROM CI_PREFERENCE ;
~';
User1 :='~
SELECT * FROM CI_PREFERENCE WHERE EMAIL_ID = lower(:APP_USER);
~';
if :G_ADMIN = 'A' then
return admin;
else
return user1;
end if;
end;
It Shows:
ORA-20001: Query must begin with SELECT or WITH error
It looks like your code is missing the Q for the alternative quoting syntax. Replace
User1 :='~
SELECT * FROM CI_PREFERENCE WHERE EMAIL_ID = lower(:APP_USER);
~';
with
User1 := q'~
SELECT * FROM CI_PREFERENCE WHERE EMAIL_ID = lower(:APP_USER);
~';
Related
How to change this SQL query to PL/SQL command line or code?
SELECT username, account_status FROM dba_users;
I tried
DECLARE
user_name VARCHAR2(20) := 'username';
account_status VARCHAR2(20) := 'account_status';
BEGIN
FOR user_name IN (SELECT username FROM dba_users) LOOP
FOR account_status IN (SELECT account_status FROM dba_users) LOOP
dbms_output.put_line(user_name.username || ' - ' || user_record.account_status);
END LOOP;
END LOOP;
END;
it works but the output is repeating
This is pure SQL:
SQL> select username, account_status from dba_users where rownum <= 5;
USERNAME ACCOUNT_STATUS
-------------------- --------------------
SYS OPEN
AUDSYS LOCKED
SYSTEM OPEN
SYSBACKUP LOCKED
SYSDG LOCKED
To "convert" it into PL/SQL, use one loop (why using two?):
SQL> set serveroutput on
SQL> begin
2 for cur_r in (select username, account_status from dba_users where rownum <= 5)
3 loop
4 dbms_output.put_line(cur_R.username ||' - '|| cur_r.account_status);
5 end loop;
6 end;
7 /
SYS - OPEN
AUDSYS - LOCKED
SYSTEM - OPEN
SYSBACKUP - LOCKED
SYSDG - LOCKED
PL/SQL procedure successfully completed.
Your code, fixed: if you use nested loops (once again, no need for that), you have to correlate one loop query to another - that's what you are missing - see line #4:
SQL> begin
2 for cur_user in (select username from dba_users where rownum <= 5) loop
3 for cur_acc in (select account_status from dba_users
4 where username = cur_user.username
5 )
6 loop
7 dbms_output.put_line(cur_user.username ||' - '|| cur_acc.account_status);
8 end loop;
9 end loop;
10 end;
11 /
SYS - OPEN
AUDSYS - LOCKED
SYSTEM - OPEN
SYSBACKUP - LOCKED
SYSDG - LOCKED
PL/SQL procedure successfully completed.
SQL>
Just use this block:
cl scr
set SERVEROUTPUT ON
BEGIN
FOR i IN (SELECT distinct username FROM dba_users order by username) LOOP
FOR j IN (SELECT distinct account_status FROM dba_users where username=i.username order by account_status) LOOP
dbms_output.put_line(i.username || ' - ' || j.account_status);
END LOOP;
END LOOP;
END;
Is there any way to assign a select query to local variable in PL/SQL other than select into statement?. Because select into throwing null value exception if the select query returns null value. Thanks
It would be helpful to post your code, but here is an example that should show the behavior you need. Assume there is a table called courses_tbl:
declare
cnumber number := NULL;
CURSOR c1
IS
SELECT course_number
FROM courses_tbl
WHERE course_name = 'XYZ';
BEGIN
open c1;
fetch c1 into cnumber;
if c1%notfound then
-- Do something here if you care about not found.
cnumber := 999; -- whatever
end if;
you can read about cursor attributes here
Seems that you need to use the exception handling as follows:
... -- Your procedure other code
BEGIN
SELECT <COLUMN_NAME> INTO <YOUR_VARIABLE>
FROM .....
WHERE ....
EXCEPTION WHEN NO DATA FOUND THEN
<YOUR_VARIABLE> := NULL;
END;
... -- Your procedure other code
You can use EXECUTE IMMEDIATE...INTO...:
DECLARE
nCnumber NUMBER;
BEGIN
EXECUTE IMMEDIATE 'SELECT CNUMBER FROM COURSES_TBL WHERE CNUMBER = 1'
INTO nCnumber;
DBMS_OUTPUT.PUT_LINE('SELECT #1 : nCnumber = ' || nCnumber);
nCnumber := NULL;
BEGIN
EXECUTE IMMEDIATE 'SELECT CNUMBER FROM COURSES_TBL WHERE CNUMBER = 100'
INTO nCnumber;
DBMS_OUTPUT.PUT_LINE('SELECT #2 : nCnumber = ' || nCnumber);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('SELECT #2 : NO DATA FOUND');
END;
END;
db<>fiddle here
You've seen how to do it using a cursor or exception handling section (which is - in my opinion - the right way to do it). However, as we're discussing, here's yet another option - an aggregate function. It won't return NO_DATA_FOUND but NULL.
This is what you have now:
SQL> declare
2 l_job emp.job%type;
3 begin
4 select job
5 into l_job
6 from emp
7 where ename = 'Does not exist';
8 end;
9 /
declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 4
This is what you might do:
SQL> declare
2 l_job emp.job%type;
3 begin
4 select max(job)
5 into l_job
6 from emp
7 where ename = 'Does not exist';
8 end;
9 /
PL/SQL procedure successfully completed.
SQL>
I am trying to increase the salary of three employees by prompting the user. The job_ids are 1, 4, and 8. I cannot seem to get my WHEN statements to work or properly interact with the datatables. Anyone have any insights?
SET SERVEROUTPUT ON
SET VERIFY OFF
accept selection prompt 'Please enter your employee ID'
DECLARE
JobNumber INT(2) := ('&selection.');
NewSalary VARCHAR2(30);
BEGIN
update emp_employee
set NewSalary = case
WHEN JobNumber = '1' THEN NewSalary := emp_employees.salary * 1.10;
WHEN JobNumber = '4' THEN NewSalary := emp_employees.salary * 1.15;
WHEN JobNumber = '8' THEN NewSalary := emp_employees.salary * 1.20;
ELSE 'Invalid ID'
END;
DBMS_OUTPUT.PUT_LINE ('Job ID '|| JobNumber || 'Salary ' || NewSalary);
END;
/
i think your update should be like below
update emp_employee
set NewSalary = case
WHEN JobNumber = 1 THEN emp_employees.salary * 1.10;
WHEN JobNumber = 4 THEN emp_employees.salary * 1.15;
WHEN JobNumber = 8 THEN emp_employees.salary * 1.20;
ELSE null
END;
//NewSalary is numeric field you can not assign string value invalid
As you didn't provide test case, I'm using Scott's schema and his EMP table. The principle is the same, though.
Have a look a this example and note the differences:
CASE you wrote is wrong; you've already said that NewSalary should be something (within the UPDATE), so you don't repeat it once again)
ELSE can't be 'Invalid ID'; you'd put a string into a NUMBER datatype column. I handled it within the IF statement - if nothing has been updated, such an employee doesn't exist.
you can't output NewSalary as you don't know it. I returned its value into a separate local variable (l_new_sal)
Also, if I were you, I'd rather create a stored procedure instead of using an anonymous PL/SQL block. If you use it for educational purposes, let it be (but you can try to convert it to a procedure, if you want).
Here you go; one example with a non-existent EMPNO, and another one for employee that exists.
SQL> set serveroutput on
SQL> set ver off
SQL> accept par_selection prompt 'Enter EMPNO: '
Enter EMPNO: 1234
SQL> declare
2 l_empno emp.empno%type := &par_selection; -- it is employee ID, not job number!
3 l_new_sal emp.sal%type;
4 l_cnt number;
5 begin
6 update emp e set
7 e.sal = case when e.deptno = 10 then e.sal * 1.1
8 when e.deptno = 20 then e.sal * 1.15
9 when e.deptno = 30 then e.sal * 1.2
10 else e.sal
11 end
12 where e.empno = l_empno
13 returning sal into l_new_sal;
14
15 l_cnt := sql%rowcount;
16
17 if l_cnt > 0 then
18 dbms_output.put_line('Employee ' || l_empno || ', new salary = ' || l_new_sal);
19 else
20 dbms_output.put_line('Nobody got new salary');
21 end if;
22 end;
23 /
Nobody got new salary
PL/SQL procedure successfully completed.
SQL> accept par_selection prompt 'Enter EMPNO: '
Enter EMPNO: 7369
SQL> /
Employee 7369, new salary = 920
PL/SQL procedure successfully completed.
SQL>
This question already has answers here:
Using variables in PLSQL SELECT statement
(2 answers)
Closed 5 years ago.
What's the basic syntax for a pl/sql variable? I'm trying to add a variable in my select statement.
My query:
DECLARE
V_id number := 251 ;
BEGIN
SELECT *
FROM client
where 1=1
and clientid = V_id;
END;
Error:
PLS-00428 an INTO clause is expected in this Select statement
This example may work for you. Please check it out
DECLARE
V_Num NUMBER(15,0) := 150;
V_Col VARCHAR2(50);
BEGIN
SELECT col1 into V_col FROM tableA where id = V_num;
END ;
I need to check a condition. i.e:
if (condition)> 0 then
update table
else do not update
end if
Do I need to store the result into a variable using select into?
e.g:
declare valucount integer
begin
select count(column) into valuecount from table
end
if valuecount > o then
update table
else do
not update
You cannot directly use a SQL statement in a PL/SQL expression:
SQL> begin
2 if (select count(*) from dual) >= 1 then
3 null;
4 end if;
5 end;
6 /
if (select count(*) from dual) >= 1 then
*
ERROR at line 2:
ORA-06550: line 2, column 6:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the following:
...
...
You must use a variable instead:
SQL> set serveroutput on
SQL>
SQL> declare
2 v_count number;
3 begin
4 select count(*) into v_count from dual;
5
6 if v_count >= 1 then
7 dbms_output.put_line('Pass');
8 end if;
9 end;
10 /
Pass
PL/SQL procedure successfully completed.
Of course, you may be able to do the whole thing in SQL:
update my_table
set x = y
where (select count(*) from other_table) >= 1;
It's difficult to prove that something is not possible. Other than the simple test case above, you can look at the syntax diagram for the IF statement; you won't see a SELECT statement in any of the branches.
Edit:
The oracle tag was not on the question when this answer was offered, and apparently it doesn't work with oracle, but it does work with at least postgres and mysql
No, just use the value directly:
begin
if (select count(*) from table) > 0 then
update table
end if;
end;
Note there is no need for an "else".
Edited
You can simply do it all within the update statement (ie no if construct):
update table
set ...
where ...
and exists (select 'x' from table where ...)
not so elegant but you dont need to declare any variable:
for k in (select max(1) from table where 1 = 1) loop
update x where column = value;
end loop;