I am querying APEX_COLLECTION view to see if a record exists and when it does not, I am getting NO_DATA_FOUND exception. To handle that I used an anonymous block:
BEGIN
SELECT c001, c002 INTO l_var1, l_var2
FROM APEX_COLLECTION
WHERE collection_name = 'TEST' AND c003='test';
EXCEPTION
WHEN NO_DATA_FOUND
l_var1 := NULL;
l_var2 := NULL;
END;
Is there a better way to handle this?
If you just want to see if a record exists, you can use de COUNT() function. In this way, it is not necessary to use anonymous blocks or NO_DATA_FOUND excepcion. The COUNT function always returns a value.
SELECT COUNT(*)
INTO l_count
FROM APEX_COLLECTION
WHERE collection_name = 'TEST' AND c003='test';
IF l_count > 0 THEN
-- Do something, the record exits
ELSE
-- Do something, the record does not exit
END IF;
Did not find better solution to my issue besides using anonymous block and capturing a NO_DATA_FOUND exception.
Use a predefined cursor and you won't be bothered with the NO_DATA_FOUND exception.
DECLARE
cursor c_apex_coll
is
SELECT c001, c002
FROM APEX_COLLECTION
WHERE collection_name = 'TEST' AND c003='test';
l_var1 varchar2(256);
l_var2 varchar2(256);
BEGIN
open c_apex_coll;
fetch c_apex_coll into l_var1, l_var2;
close c_apex_coll;
END;
Related
I want the following trigger to be run correctly but it rise an error which is: bad bind variable 'P23_ID'.
The trigger query is:
Create or replace trigger "newTRG"
Before
Insert on "my_table"
For each row
Begin
If :new."ID" is null then
Insert into my_table (ID) values (:P23_ID);
end if;
End;
Use the v() syntax:
create or replace trigger "newTRG" before
insert on "my_table"
for each row
begin
if :new."ID" is null then
insert into my_table ( id ) values (v('P23_ID'));
end if;
end;
On a side note, if this is a primary key value it is a lot easier to use identity columns (the new way) or a sequence (the old way) to populate your column. Doing this from a page item is error prone.
Im trying to write a procedure that updates the domain of an email (example: converting Email123#gmail.com into Email123#hotmail.com when i pass 2 strings gmail.com and hotmail.com) while having a cursor in my procedure
create of replace procedure pr_update_email
(Old_Email Varchar2, New_Email Varchar2)
As
V_OldDomain Varchar2(50);
Cursor C_Domains IS Select Email_Address
From Customer
where Email_Address Like '%#'||Old_Email;
Begin
Open C_Domains;
Fetch C_Domains INTO V_OldDomain;
While C_Domains %Found loop
Update Customer
Set Email_Address = regexp_replace(Email_Address, '^(.*#.*)'||Old_Email||'\1'||New_Email)
WHERE Email_Address LIKE V_OldDomain;
Fetch C_Domains into New_Email;
End Loop;
Close C_Domains;
End pr_update_email;
/
Show Errors;
getting errors:
19/11 PL/SQL: SQL Statement ignored
19/32 PLS-00403: expression'NEW_EMAIL' cannot be used as an INTO-target of a
SELECT/FETCH statement
You can directly update without creating a Stored Procedure but by using Regexp_Replace() and Instr() Functions :
SQL> Update Customer
Set Email_Address = Regexp_Replace(Email_Address,'(.*)#[gmail]+.(.*)','\1#hotmail.\2')
Where Instr(Email_Address,'#gmail.') > 0;
SQL> Commit;
If you want to create a generic structure in order to be able to use for such other cases also, then transfer the above Update statement as :
SQL> Create Or Replace Procedure pr_update_email(Old_Email Varchar2, New_Email Varchar2) As
Begin
Update Customer
Set Email_Address = Regexp_Replace(Email_Address,'(.*)#['||Old_Email||']+.(.*)','\1#'||New_Email||'.\2')
Where Instr(Email_Address,'#'||Old_Email||'.')>0 ;
End;
/
SQL> Begin
pr_update_email('gmail','hotmail');
End;
/
SQL> Commit;
Why you are using the cursor? It can be handled using simple update statement.
Your procedure should look like this:
create procedure pr_update_email (p_oldemail in varchar2,
p_newemail in varchar2)
As
Begin
UPDATE BROKER
SET
EMAIL_ADDRESS = REPLACE(EMAIL_ADDRESS, p_oldemail, p_newemail)
WHERE
REGEXP_LIKE ( EMAIL_ADDRESS,'.*#'|| p_oldemail|| '$' );
Commit;
End;
/
Or if you really want to use the loop then
create of replace procedure pr_update_email
(Old_Email Varchar2, New_Email Varchar2)
As
Begin
For i in (Select Email_Address
From Customer
where Email_Address Like '%#'||Old_Email) loop
Update Customer
Set Email_Address = Replace(Email_Address, old_email, new_email)
WHERE Email_Address = i.Email_Address;
End Loop;
Commit;
End pr_update_email;
/
To call this procedure, you need to pass both the domain as following:
Begin
pr_update_email('gmail.com', 'hotmail.com');
End;
/
And Yes, Issue in your code is following line:
Fetch C_Domains into New_Email;
New_Email is an input parameter and you can not assign any value to the input parameter.
Cheers!!
I have the following code:
DECLARE
i NUMBER;
BEGIN
SELECT COUNT(*) INTO i FROM apex_collections where collection_name = 'COLLECTION';
if i = 0 then
apex_error.add_error(
p_message => 'Invalid Excel file!'
, p_display_location => apex_error.c_inline_with_field
, p_page_item_name => 'P3_BROWSE_EXCEL'
);
end if;
END;
All it does is check if a collection exists. If not, it should raise an error.
I am calling this from a Process, so an Alert or something similar is no alternative.
Instead of showing the correct error message next to the P3_BROWSE_EXCEL - item, it shows this error on top of the page:
1 error has occurred
Error: Not found
I am 100% sure P3_BROWSE_EXCEL exists on that page, so why?
Why don't you use simple SQL validation? Validation Type - Rows returned, the query
SELECT 1 FROM apex_collections where collection_name = 'COLLECTION';
Display location - Inline with field, Associated Item - you can choose an item from a list with 100% guarantee that it exists.
At opencart2.0, I want to create a ocmod extension, In install.sql, I need to modify the database field. When I modify the database field, I need to decide if the field exists. Ive tried multiple variations of this, but none of them seem to work. Any ideas? Thanks in advance.
this is my install.sql,but is error
DROP PROCEDURE IF EXISTS add_col_need_credit;
DELIMITER $$ CREATE PROCEDURE add_col_need_credit() BEGIN IF NOT EXISTS(SELECT column_name FROM information_schema.columns WHERE table_name='oc_customer_group_description' AND column_name='need_credit' ) THEN ALTER TABLE `oc_customer_group_description` ADD `need_credit` numeric(10,4) NOT NULL default 0; END IF;END$$ DELIMITER ;
CALL add_col_need_credit();
this is not error,you can in mysql console use it
DROP PROCEDURE IF EXISTS add_col_need_credit;
DELIMITER $$ CREATE PROCEDURE add_col_need_credit() BEGIN IF NOT EXISTS(SELECT column_name FROM information_schema.columns WHERE table_name='oc_customer_group_description' AND column_name='need_credit' ) THEN ALTER TABLE `oc_customer_group_description` ADD `need_credit` numeric(10,4) NOT NULL default 0; END IF;END$$ DELIMITER ;
CALL add_col_need_credit();
DROP PROCEDURE IF EXISTS add_col_need_credit;
DELIMITER $$ CREATE PROCEDURE add_col_need_credit() BEGIN IF NOT EXISTS(SELECT column_name FROM information_schema.columns WHERE table_name='oc_customer_group_description' AND column_name='need_credit' ) THEN ALTER TABLE `oc_customer_group_description` ADD `need_credit` numeric(10,4) NOT NULL default 0; END IF;END$$ DELIMITER ;
CALL add_col_need_credit();
create or replace
TRIGGER TR_SITECONTACT_UPDATE
AFTER UPDATE OR INSERT ON s_ct
FOR EACH ROW
DECLARE
v_SID s_ct.sid%type;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF :NEW.CTID != :OLD.CTID THEN
UPDATE CT
SET lastupdatedon =sysdate,
LASTUPDATESITE=:NEW.SID
WHERE CTID = :NEW.CTID;
COMMIT;
END IF;
END;
Here it's possible to check whether lastupdatedCOF is null or not then use update statement, before update row i need to check lastupdatedCOF IS NULL OR NOT in CT Table. IF Null means i need to use below update statement
UPDATE CT
SET lastupdatedon =sysdate,
LASTUPDATESITE=:NEW.SID
WHERE CTID = :NEW.CTID;
COMMIT;
lastupdatedCOF IS NOT NULL Means
UPDATE CT
SET lastupdatedon =sysdate,
LASTUPDATESITE=:NEW.SID,
lastupdatedCOF = NULL
WHERE CTID = :NEW.CTID;
COMMIT;
If I read your question, either lastupdatedCOF is null (in which case, it remains null) or lastupdated_cof is not null and you want to set it to null.
So, why not just always set it to null?
I.e.:
create or replace
TRIGGER TR_SITECONTACT_UPDATE
AFTER UPDATE OR INSERT ON s_ct
FOR EACH ROW
DECLARE
v_SID s_ct.sid%type;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
IF :NEW.CTID != :OLD.CTID THEN
UPDATE CT
SET lastupdatedon =sysdate,
LASTUPDATESITE=:NEW.SID,
lastupdatedCOF = NULL
WHERE CTID = :NEW.CTID;
COMMIT;
END IF;
END;
One other point - do you really, really need an autonomous transaction? What if the transaction inserting into/updating the s_ct table is rolled back - as things stand, you'd be left with a row in the CT table that's been changed, despite the underlying change not having taken place.