You need the INTO
clause for both SELECT
statements.
However, do you really need to use PL/SQL?
You could do it all in SQL, avoiding context switches with:
SELECT *
FROM bc
WHERE TRUNC(ADD_MONTHS(SYSDATE, -1)) BETWEEN bc_start_date AND bc_end_date;
Or, you could rewrite what you have so there is only one switch to SQL from within your PL/SQL block as:
DECLARE
TYPE bc_tabtype IS TABLE OF bc%ROWTYPE
INDEX BY pls_integer;
--
bc_tab bc_tabtype;
BEGIN
SELECT *
BULK COLLECT INTO bc_tab
FROM bc
WHERE TRUNC(ADD_MONTHS(SYSDATE, -1)) BETWEEN bc_start_date AND bc_end_date;
-- Do what you want with the results you now have in the Associative Array bc_tab
END;
You might need to look up associative arrays and BULK COLLECT etc. to understand them.
Tom Kyte, the Oracle VP states it succinctly when he says:
I have a pretty simple mantra when it comes to developing database software, and I have written this many times over the years:
You should do it in a single SQL statement if at all possible. If you cannot do it in a single SQL statement, do it in PL/SQL. If you cannot do it in PL/SQL, try a Java stored procedure. If you cannot do it in Java, do it in a C external procedure. If you cannot do it in a C external procedure, you might want to seriously think about why it is you need to do it.
EDIT: In light of your comment, try this:
DECLARE
v_bc_mth DATE := TRUNC(ADD_MONTHS(SYSDATE, -1));
--
TYPE bc_tabtype IS TABLE OF bc%ROWTYPE
INDEX BY pls_integer;
--
bc_tab bc_tabtype;
BEGIN
SELECT *
BULK COLLECT INTO bc_tab
FROM bc
WHERE v_bc_mth BETWEEN bc_start_date AND bc_end_date;
END;