I’m using Oracle apex and am trying to practice with automatic emails. Ideally, this is how the scenario would go: A user can ‘recommend’ games to friends through his wishlist. The user selects the game(s) they would like to recommend though a checkbox, then selects the friends and email content. The code I have in place for this is as follows:
DECLARE
content VARCHAR2(4000) := :P4_EMAIL || 'Here are the game(s):';
game VARCHAR2(100);
i NUMBER := 1;
/*Declare the cursor and it's query */
cursor CURSOR IS
SELECT name
from gs_games
where game_id = APEX_APPLICATION.G_F01(i)
FOR UPDATE;
BEGIN
FOR i in 1..APEX_APPLICATION.G_F01.count
LOOP
OPEN cursor;
FETCH cursor INTO game;
CLOSE cursor;
END LOOP;
htmldb_mail.Send(p_to => :P4_FRIENDS,
p_from => 'gametracker@gametracker.com',
p_subj => 'Game recommendations from ' || :F56_USER_NAME,
p_body => content || ' ' || game);
END;
This only partially works. For a single selection, everyone works perfectly, but once the user selects multiple games, then the email only contains the name of the first game checked off, instead of every game as it should. I realize this is tied to the way I’ve got my cursor set up, but I’m not entirely sure how I can use it while keeping that for loop active. Does anyone have any ideas? Thank you.
The immediate problem is that every time you fetch the next row from the cursor into your local variable
game, you are overwriting the prior value of that variable. Once you’ve fetched every row from the cursor,gamewill have the value of whatever the last row you processed was.Assuming that you want your email to contain a comma-separated list of game names, you could do something like
A few notes about style
CURSORis problematic and should be avoided at all costs. If you do need to declare a cursor, you really ought to give it a meaningful name.l_prefix for local variables and ap_prefix for parameters though there are many different valid conventions. This is important in PL/SQL because identifiers in SQL statements are resolved first using the names of columns in the table and then using local variables. That makes it far too easy to inadvertently write code that uses a column when you meant for it to use a local variable if you don’t have some convention to make it clear which you’re using.SELECT INTO.namefor a particulargame_idbecause that maximizes reuse– there will likely be many other places that you need to do something similar so you want to write that code once and use it many times. It would be perfectly legal to put theSELECT INTOinto the loop in your anonymous PL/SQL block, it would be preferable to factor that code out into a function.apex_mailpackage not the oldhtmldb_mailpackage. There shouldn’t be any functional difference between the two but HTML DB was the old name for Oracle APEX many releases ago so it’s a good idea to phase out the use of the old package names.