Domanda

I was writing a PL/SQL procedure to come up with a report.

Here is part of my scripts where I tested and had the compilation error.

I believe it's not the syntax of the select into clause, but I don't know the exact problem when assigning value to the date variables...

Did anyone encounter this error before?

DECLARE
  v_bc_mth DATE;
BEGIN
  SELECT TRUNC(ADD_MONTHS(SYSDATE, -1)) INTO v_bc_mth FROM dual; --what's wrong with the clause
  SELECT * FROM bc WHERE v_bc_mth BETWEEN bc_start_date AND bc_end_date;
END;

PLS-00428: an INTO clause is expected in this SELECT statement 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error.

È stato utile?

Soluzione

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top