I test sql querys.
IF 3 = 3 THEN
SELECT 'TRUE'
ELSE
SELECT 'FALSE'
END IF;
I excuted that query on SQLyog.
I got the error message below.
You have an error in your SQL syntax; check the manual that corresponds to
your MariaDB server version for the right syntax to use near 'ELSE SELECT
'FALSE' END IF' at line 3
That query is very simple. I don't know why happen error message.
IF itself is not a query, it cannot be executed as a standalone statement.
There are two different IFs that you can use.
One is the conditional construct in compound statements. It can be used in stored routines:
DELIMITER $
CREATE PROCEDURE pr()
BEGIN
IF 3 = 3 THEN
SELECT 'TRUE';
ELSE
SELECT 'FALSE';
END IF;
END $
DELIMITER ;
CALL pr;
Or, if you are running a reasonably new version of MariaDB (10.1+), you can also use it in an anonymous block:
DELIMITER $
BEGIN NOT ATOMIC
IF 3 = 3 THEN
SELECT 'TRUE';
ELSE
SELECT 'FALSE';
END IF;
END $
DELIMITER ;
Another is the IF function, which can be used inside a query:
SELECT IF(3 = 3 THEN 'TRUE','FALSE');
You need semicolons at the end of each inner statement like so:
IF 3 = 3 THEN
SELECT 'TRUE';
ELSE
SELECT 'FALSE';
END IF;
Related
Here is a ksh :
$ORACLE_HOME/bin/sqlplus id/psw#$ORACLE_SID #$P_SQL/mysql.sql $1
return_code=$?
echo return_code
Here is the sql :
set serverout on
var error number
...
declare
error number(1) := 0;
begin
.......
exception
when too_many_rows then
error := 2;
end;
/
exit
How to pass the PLSQL error value to SQLPLUS variable and then the SqlPlus variable to the ksh variable return_code.
Thank you
It is possible to pass a SQL error code from a PL/SQL script to the shell.
However, the shell will perform modulo 256 on the SQL error number. If you needed a specific number, you could use a user defined error with a custom error number.
SET SERVEROUT ON
WHENEVER SQLERROR EXIT SQL.SQLCODE;
DECLARE
l_result VARCHAR2(1);
BEGIN
SELECT result
INTO l_result
FROM (SELECT 'A' result
FROM dual
UNION
SELECT 'B' result
FROM dual);
EXCEPTION
WHEN too_many_rows THEN
Raise_application_error(-20226, 'Custom error ' || MOD(20226, 256) || ' for too many rows');
END;
/
exit
Trying to dynamically generate and execute a PL/SQL statement. It doesn't return results, but executing okay. What I am trying is to get the table name from the schema in first statement (got it right!), and append that to a select statement, and then execute it to return the table results.
DECLARE
LATEST_TABLE VARCHAR2(256);
PostalCode ADM.POSTAL_CODE_201801%ROWTYPE;
BEGIN
SELECT TO_CHAR(max(table_name)) INTO LATEST_TABLE FROM all_tables WHERE owner = 'ADM' AND table_name LIKE 'POSTAL_CODE_%';
LATEST_TABLE := 'begin Select POSTALCODE,LONGITUDE,LATITUDE,MUNICIPALITY_FULL_NAME,LOCAL_NAME,SZONE_NAME,ZONE_NAME,RHA_CODE,RHA_NAME,URBAN,ZONE_RURAL from ADM.'||LATEST_TABLE||' ;end;';
execute immediate LATEST_TABLE into PostalCode;
Exception
When others then
Null;
END;
Why am I not getting any results? Adding
dbms_output.put_line(PostalCode.LONGITUDE || PostalCode.LATITUDE); after execute immediate is also not generating results!
I see a couple of issues here; your code is something like:
declare
vSQL varchar2(1000);
vTabName varchar2(30);
vResult number;
begin
select table_name into vTabName from user_tables;
vSQL := 'begin select a from ' || vTabName || '; end;';
execute immediate vSQL into vResult;
dbms_output.put_line('REsult: ' || vResult);
exception
when others then
null
end;
If you run this, you see nothing, because the dynamic part gives error, but the (dangerous) exception handling hides it; if you would edit the null; into something like
dbms_output.put_line('Error: ' || sqlerrm);
you would get:
Error: ORA-06550: line 1, column 7:
PLS-00428: an INTO clause is expected in this SELECT statement
In fact you dynamic code is like
begin select a from someTable; end;
and this gives error.
A way to do what you need could be:
...
vSQL := 'select a from ' || vTabName;
execute immediate vSQL into vResult;
...
I have the following code:
declare
y pls_integer := 0;
v_msg varchar2(4000);
plsql varchar(4000);
begin
if not apex_collection.collection_exists(p_collection_name=>'P16_COLLECTION') then
wwv_flow.debug('No Apex collection found!');
else
for x in (select * from apex_collections where collection_name = 'P16_COLLECTION' and seq_id > 1 order by seq_id)
loop
y := y+1;
FOR i IN 1..25
LOOP
plsql := 'begin apex_collection.update_member_attribute (p_collection_name=> ''P16_COLLECTION'', p_seq=>' || TO_CHAR(x.seq_id) || ',p_attr_number =>' || TO_CHAR(i) || ',p_attr_value=>wwv_flow.g_f' || TO_CHAR(i, 'FM00') || '(' || TO_CHAR(y) || ')); end;';
wwv_flow.debug(plsql);
EXECUTE IMMEDIATE plsql;
END LOOP;
end loop;
end if;
exception when others then
v_msg := ''||sqlerrm;
wwv_flow.debug('ERR: '||v_msg);
end;
This code is very similar to the one proposed here, but I loop through 25 columns. The issue with Oracle Apex is the max number of chars PL/SQL is allowed to have, so I am unable to just write 25 update_member_attribute - calls.
But instead of a it excecuting I get an error no data found.
I triple checked that the collection P16_COLLECTION exists.
The issue with Oracle Apex is the max number of chars PL/SQL is allowed to have
I'm not sure I understood this statement. It is PL/SQL you use. You declared a local PLSQL variable as VARCHAR2(4000). Why didn't you specify its max allowed size, 32767? Would that help?
Furthermore, saying that you got NO-DATA-FOUND exception: are you sure that this piece of code raised it? Because, there's no SELECT statement in there ... the one you used in a cursor FOR loop can't raise NO-DATA-FOUND; UPDATE either. Therefore, it must be something else, I presume.
Enable DEBUG, run the page and - when you get the error - view debug results and locate the culprit.
The PL/SQL procedure below:
'DECLARE
V_EMPNO NUMBER(10):=&EMPNO;
V_EMPNO2 NUMBER(10):= 0;
CURSOR C1 IS SELECT EMPNO FROM EMP;
BEGIN
FOR I IN C1 LOOP
FETCH C1 INTO V_EMPNO2;
EXIT WHEN C1%FOUND;
END LOOP;
IF (LENGTH(V_EMPNO)) > 4 THEN
DBMS_OUTPUT.PUT_LINE ('LENGTH OF EMPNO GREATER THAN 4 NUMBER');
ELSIF (V_EMPNO = V_EMPNO2) THEN
DBMS_OUTPUT.PUT_LINE ('THIS EMPLOYEE NUMBER ALREADY EXIST');
END IF;
END;
/'
In this procedure I want show two messages
one is if lenght greater than number 4 than show message
and second is if v_empno = v_empno2 then show second message
empno = v_empno then show message:
DBMS_OUTPUT.PUT_LINE ('THIS EMPLOYEE NUMBER ALREADY EXIST')
this is error
Enter value for empno: 4444
DECLARE
*
ERROR at line 1:
ORA-01001: invalid cursor
ORA-06512: at line 7
FOR I IN C1 LOOP
already implicitly opens c1 and handles the fetching, so your explicit fetch after it is invalid.
btw i is normally used for numeric indexes rather than records.
Also your caps lock was on when you wrote that code ;)
I think there are a couple of problems with your code.
C1 does not restrict on employee number (meaning the loop will
return a single, largely random row from table emp
You are mixing FOR LOOP and FETCH syntax
Variable v_empno is a NUMBER and you need to be careful when checking the length - you need to explicitly TO_CHAR and control the format - often TO_CHAR will end up including space characters (an alternative would be to check the value of a number is < 10000)
I've not tested this code but this might be closer to what you're after :
DECLARE
l_empno NUMBER := &empno ;
CURSOR C_get_emp
IS
SELECT e.empno
FROM emp e
WHERE e.empno = l_empno
;
R_emp C_get_emp%ROWTYPE ;
BEGIN
IF LENGTH(TRIM(TO_CHAR(l_empno))) > 4 THEN
DBMS_OUTPUT.put_line('Length of empno > 4') ;
ELSE
OPEN C_get_emp ;
FETCH C_get_emp INTO R_emp ;
IF C_get_emp%FOUND THEN
DBMS_OUTPUT.put_line('Employee number already exists') ;
END IF ;
CLOSE C_get_emp ;
END IF ;
END ;
hi I wrote this code to create a procedure to return a Boolean value based on the if conditions but when I execute it I got this error:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'DDPAY_SP'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
here is my procedure
create or replace procedure DDPAY_SP (
donor_id dd_donor.iddonor%type,
pldgstatus out dd_pledge.idstatus%type,
monthplan out dd_pledge.paymonths%type,
ret out boolean)
IS
begin
select idstatus, paymonths into
pldgstatus, monthplan from dd_pledge
where iddonor = donor_id ;
if (pldgstatus = 10 AND monthplan >0)
then ret:= true;
else
ret:= false;
end if;
end;
and this how I execute it
EXECUTE DDPAY_SP (308);
I didn't put much talk I hope it's clear enough for you
I read online it recommends me to check the naming also the data type which I did but nothing change
any ideas
If you don't need the second and third arguments you could declare those as variables in the procedure instead of arguments, as follows:
CREATE OR REPLACE PROCEDURE DDPAY_SP(DONOR_ID IN DD_DONOR.IDDONOR%TYPE,
RET OUT BOOLEAN)
IS
nPayment_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO nPayment_count
FROM DD_PLEDGE p
WHERE p.IDDONOR = DONOR_ID AND
p.IDSTATUS = 10 AND
p.PAYMONTHS > 0;
IF nPayment_count > 0 THEN
RET := TRUE;
END IF;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('DD_PAY - exception: ' || SQLCODE || ' : ' || SQLERRM);
RAISE;
END DDPAY_SP;
I've included an example of an EXCEPTION handler at the end of DD_PAY. It's always a good idea to include at least this minimal handler so that in the event an exception occurs you'll get some indication of where the problem lies.
Because this procedure returns a BOOLEAN value, and BOOLEANs cannot (to the best of my knowledge) be used from SQL*Plus, you'll have to invoke it from a PL/SQL block, as follows:
DECLARE
bRetval BOOLEAN;
BEGIN
DD_PAY(308, bRetval);
DBMS_OUTPUT.PUT_LINE('Returned value is ' ||
CASE bRetval
WHEN TRUE THEN 'TRUE'
ELSE 'FALSE'
END);
END;
Give that a try.
EDIT: rewrote procedure based on further information from later comments.
Share and enjoy.