Bellow is my procedure.
create or replace procedure my_log (action in varchar2, message in varchar2 )
is
begin
Insert into my_log_table (ACTION, MESSAGE, EVENT_DATE)
values (action, message, sysdate);
commit;
end;
/
CREATE OR REPLACE PROCEDURE "CUSTOMER_INCREMENTAL" ()
IS
err_num NUMBER;
err_msg VARCHAR2(4000);
BEGIN
my_log ('Start','My message');
INSERT INTO NDB_AML_CUSTOMER
(ID, TITLE,...)
SELECT ID, TITLE,...
FROM NDB_CUSTOMER_NEW
WHERE DATE_TIME > (SELECT RUN_DATE FROM CHECK_POINT WHERE TABLE_NAME = 'NDB_CUSTOMER_NEW');
UPDATE CHECK_POINT SET RUN_DATE = SYSDATE WHERE TABLE_NAME = 'NDB_CUSTOMER_NEW';
COMMIT;
my_log ('End','My message');
EXCEPTION
WHEN OTHERS THEN
err_num := SQLCODE;
err_msg := SQLERRM;
my_log ('Error' , errnum ||' - ' || err_msg);
END;
/
When I compile it gives the error PLS-00103: Encountered the symbol ")" when expecting one of the following: current delete exists prior. Any suggestions?
You do not need () if function or procedure has no parameters.
Related
whenever i call this function it will return error like - invalid cursor
so, this is the body part of the package, the package specification also return a sys_refcursor. the error message shows that sys_refcursor invalid cursor.
FUNCTION SUMMARY
(i_name VARCHAR2, i_id VARCHAR2, i_label VARCHAR2)
RETURN SYS_REFCURSOR
IS
rc_result SYS_REFCURSOR;
v_sql CLOB;
Server VARCHAR2(100) := '#AI';
v_r_count NUMBER;
v_sp_count VARCHAR2(200);
V VARCHAR2(10);
BEGIN
EXECUTE IMMEDIATE 'select count(*) from run'||Server||' where id='''||i_id||''' and label='''||i_label||''' and re is not null' INTO v_r_count;
EXECUTE IMMEDIATE 'select table_name from all_tables where table_name like ''%se%'' and owner ='''||i_name||'''' INTO v_sp_count;
IF v_r_count > 0 THEN
BEGIN
v_sql := 'select RE from run'||v_Server||' where id='''||i_id||''' and label='''||i_label||'''';
END;
ELSIF v_sp_count IS NOT NULL THEN
BEGIN
v_sql := 'SELECT
process,
desc,
p_desc,
date
FROM
'||i_name||'.se
WHERE
errors = 1
AND lower(p_desc) LIKE lower(''%summary%'')';
END;
ELSE v_sql := NULL;
END IF;
OPEN result FOR v_sql;
RETURN result;
EXCEPTION
WHEN no_data_found THEN
RETURN NULL;
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
END;
You can simply assign NULL to the refcursor like this: Example
PROCEDURE test( id_number IN VARCHAR2,
resultIN OUT SYS_REFCURSOR) AS
BEGIN
if false then
OPEN resultIN FOR
SELECT dummy
from dual;
ELSE
resultIN := null;
END IF;
END;
I created a function and it uses a dynamic sql:
create function check_ref_value
(
table_name varchar2,
code_value number,
code_name varchar2
) return number is
l_query varchar2(32000 char);
l_res number;
begin
l_query := '
select sign(count(1))
into :l_res
from '|| table_name ||'
where '|| code_name ||' = :code_value
';
execute immediate l_query
using in code_value, out l_res;
return l_res;
end;
But when I try to use it I get an exception "ORA-00933: SQL command not properly ended"
What is wrong with this code?
You can use EXECUTE IMMEDIATE ... INTO ... USING ... to get the return value and DBMS_ASSERT to raise errors in the case of SQL injection attempts:
create function check_ref_value
(
table_name varchar2,
code_value number,
code_name varchar2
) return number is
l_query varchar2(32000 char);
l_res number;
begin
l_query := 'select sign(count(1))'
|| ' from ' || DBMS_ASSERT.SIMPLE_SQL_NAME(table_name)
|| ' where ' || DBMS_ASSERT.SIMPLE_SQL_NAME(code_name)
|| ' = :code_value';
execute immediate l_query INTO l_res USING code_value;
return l_res;
end;
/
Which, for the sample data:
CREATE TABLE abc (a, b, c) AS
SELECT 1, 42, 3.14159 FROM DUAL;
Then:
SELECT CHECK_REF_VALUE('abc', 42, 'b') AS chk FROM DUAL;
Outputs:
CHK
1
And:
SELECT CHECK_REF_VALUE('abc', 42, '1 = 1 OR b') AS chk FROM DUAL;
Raises the exception:
ORA-44003: invalid SQL name
ORA-06512: at "SYS.DBMS_ASSERT", line 160
ORA-06512: at "FIDDLE_UVOFONEFDEHGDQJELQJL.CHECK_REF_VALUE", line 10
As for your question:
What is wrong with this code?
Using SELECT ... INTO is only valid in an SQL statement in a PL/SQL block and when you run the statement via EXECUTE IMMEDIATE it is executed in the SQL scope and not a PL/SQL scope.
You can fix it by wrapping your dynamic code in a BEGIN .. END PL/SQL anonymous block (and reversing the order of the bind parameters in the USING clause):
create function check_ref_value
(
table_name varchar2,
code_value number,
code_name varchar2
) return number is
l_query varchar2(32000 char);
l_res number;
begin
l_query := '
BEGIN
select sign(count(1))
into :l_res
from '|| DBMS_ASSERT.SIMPLE_SQL_NAME(table_name) ||'
where '|| DBMS_ASSERT.SIMPLE_SQL_NAME(code_name) ||' = :code_value;
END;
';
execute immediate l_query
using out l_res, in code_value;
return l_res;
end;
/
(However, that is a bit more of a complicated solution that just using EXECUTE IMMEDIATE ... INTO ... USING ....)
db<>fiddle here
I have ORACLE PROCEDURE, where I need to use dynamic table name in select query based on parameter "a_ID" passed.
But I am getting error in creating procedure.
Error(20,28): PL/SQL: ORA-00942: table or view does not exist
Can anybody help resolving this?
Below is the proc....
CREATE OR REPLACE
PROCEDURE IsTrue
(
AppID IN VARCHAR2,
a_ID IN VARCHAR2,
l_ID VARCHAR2,
return_value out CHAR
)
AS
v_sql VARCHAR(3000);
v_tablename VARCHAR(30);
BEGIN
SELECT decode(a_ID,'LS','LSAPP','MR','MRAPP','RV','RVAPP','APP') INTO v_tablename FROM dual;
SELECT CASE
WHEN EXISTS (SELECT 1
FROM v_tablename
WHERE APPID = AppID
AND LID <> l_ID)
THEN 'Y'
ELSE 'N'
END AS RECORD_EXISTS
FROM DUAL;
EXECUTE IMMEDIATE v_sql INTO return_value;
END;
CREATE OR REPLACE PROCEDURE IsTrue (argAppID IN VARCHAR2, a_ID IN VARCHAR2, l_ID VARCHAR2, return_value out CHAR )
AS
v_sql VARCHAR(3000);
v_tablename VARCHAR(30);
BEGIN
SELECT decode(a_ID,'LS','LSAPP','MR','MRAPP','RV','RVAPP','APP') INTO v_tablename FROM dual;
v_sql := 'SELECT CASE WHEN EXISTS (SELECT 1 FROM ' || v_tablename || ' WHERE APPID = '''|| argAppID ||''' AND LID <> '''|| l_ID || ''') THEN ''Y'' ELSE ''N'' END AS RECORD_EXISTS FROM DUAL';
EXECUTE IMMEDIATE v_sql INTO return_value;
END;
In your procedure the second line created as dynamic sql and stored in v_sql.
This may help your procedure to execute as you need.
I wrote the following Package.
When I compile it I got the following error:
PLS-00103: Encountered the symbol "("
Line 42 Column 66
Which is "PROCEDURE p_fail "
I am helpless. I searched the Internet but found nothing what helps me.
Does anyone has an idea?
Many thanks in advance.
CREATE OR REPLACE PACKAGE BODY boxi_rep.pck_jk_test AS
PROCEDURE p_main
IS
err_num NUMBER;
err_msg VARCHAR2 (200);
BEGIN
boxi_rep.pck_jk_test.p_start;
boxi_rep.pck_jk_test.p_truncate;
EXCEPTION
WHEN OTHERS
THEN
err_num := SQLCODE;
err_msg := SUBSTR (SQLERRM, 1, 200);
boxi_rep.pck_jk_test.p_fail (err_num, err_msg);
END;
PROCEDURE p_start
IS
BEGIN
/*Make start entry into Log_Jobs*/
DELETE FROM log_jobs
WHERE job_id = '1501'
AND TRUNC (datum) = TRUNC (SYSDATE)
AND end_timestamp IS NULL;
INSERT INTO log_jobs (job_id,
job_name,
datum,
start_timestamp)
VALUES ('1501',
'V$Re_Schedule TEST',
TRUNC (SYSDATE),
SYSDATE);
COMMIT;
END;
PROCEDURE p_fail (in_err_code IN NUMBER, in_err_msg IN VARCHAR2 (200))
IS
BEGIN
UPDATE log_jobs
SET end_timestamp = SYSDATE,
status = 'FAILED - ' || in_err_code || ' - ' || in_err_msg,
duration = TO_CHAR (TO_DATE ('00:00:00', 'hh24:mi:ss') + (SYSDATE - start_timestamp), 'hh24:mi:ss')
WHERE job_id = '1501'
AND end_timestamp IS NULL;
COMMIT;
END;
PROCEDURE p_truncate
IS
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE boxi_rep.jk_test';
END;
END pck_jk_test;
See http://docs.oracle.com/cd/B19306_01/appdev.102/b14251/adfns_packages.htm#i1006401
Numerically constrained types such as NUMBER(2) or VARCHAR2(20) are not allowed in a parameter list.
Change
PROCEDURE p_fail (in_err_code IN NUMBER, in_err_msg IN VARCHAR2 (200))
to
PROCEDURE p_fail (in_err_code IN NUMBER, in_err_msg IN VARCHAR2)
Size of varchar2 is not allowed with in and out partameter
PROCEDURE p_fail (in_err_code IN NUMBER, in_err_msg IN VARCHAR2)
IS
BEGIN
UPDATE log_jobs
SET end_timestamp = SYSDATE,
status = 'FAILED - ' || in_err_code || ' - ' || in_err_msg,
duration = TO_CHAR (TO_DATE ('00:00:00', 'hh24:mi:ss') + (SYSDATE - start_timestamp), 'hh24:mi:ss')
WHERE job_id = '1501'
AND end_timestamp IS NULL;
COMMIT;
END;
declare
e_forall_error exception;
pragma exception_init(e_forall_error,-24381)
;
type t_numbers is table of emp.empno%type;
l_numbers t_numbers := t_numbers(null,2,3,4,5,6,7,8,9,10)
;
begin
forall i in 1..l_numbers.count save exceptions
--note:empno is primary key
insert into emp
( empno , ename
)
values
( l_numbers(i)
, 'Name' || to_char(l_numbers(i))
)
;
exception
when e_forall_error then
for i in 1..sql%bulk_exceptions.count
loop
dbms_output.put_line('SQLCODE: ' || sql%bulk_exceptions(i).error_code);
dbms_output.put_line('SQLERRM: ' || sqlerrm(-sql%bulk_exceptions(i).error_code));
dbms_output.new_line;
end loop;
end;
/
HI all , i have an exisiting procedure which is inserting the value of empno and empname into emp table as shown above,but the problem is that the error mentioned by the procedure is
SQLCODE: 1400
SQLERRM: ORA-01400: cannot insert NULL into ()
I want a more specific error ,what it usually throw like
SQLERRM: ORA-01400: cannot insert NULL into empno column
How can this been possible in bulk insert?
CREATE OR REPLACE TABLE logs (logcode NUMBER, logmsg VARCHAR2(1024));
/
CREATE OR REPLACE PROCEDURE logme(I_logcode IN NUMBER, I_logmsg IN VARCHAR2) IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
insert into logs (logcode, logmsg) values (I_logcode , I_logmsg);
commit;
END;
/
CREATE OR REPLACE PROCEDURE insertmyrow(I_prm1 IN VARCHAR2, I_prm2 IN VARCHAR2, ...) IS
BEGIN
insert into emp (empno, ename, ...) values (I_prm1, I_prm2, ...);
EXCEPTION WHEN OTHERS THEN
logme(sqlcode, sqlerrm);
RAISE;
END;
/
forall i in 1..l_numbers.count save exceptions
insertmyrow(l_numbers(i), ...);
This is the main idea and I guess a bit heavy maybe but why not?