Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I declare and initialize a package variable by SELECT

Can someone help me understand why I can declare a hardcoded date value in a package but not assign the value from a query? I've seen a number of examples (including the reference book) that show declarations of hardcoded values but I'm unable to locate examples of assigning values to variable through queries.

This is allowed:

create or replace package body PACKAGE_NAME AS
    tDate DATE := '2012-05-30';
    -- ...procedures follow

This is allowed:

create or replace package body PACKAGE_NAME AS
    tDate DATE := sysdate;

This is not allowed:

create or replace package body PACKAGE_NAME AS
    tDate DATE := select MAX(date_) from Table_Name;

I've tried a number of ways and I'm ok with it not working - I can use it as needed in the procedures themselves. But I'd like to know why I can't assign a value to tDate this way? The specific error is:

Encountered the symbol 'SELECT' when expecting ....

Adding that I can get variable values assigned through queries in a stored procedure but the same process does not seem to work for package body.

PROCEDURE Proc_Name IS
tDate Date;
BEGIN
SELECT MAX(date_) into tDate from Table_Name;
like image 565
dee Avatar asked Jun 01 '12 14:06

dee


1 Answers

You need to create a package initialization block in your package body. This is a relatively arcane bit of PL/SQL package lore, but it's there and can be used. Here's an example:

CREATE OR REPLACE PACKAGE TEST_PKG IS
  tDate  DATE;
END TEST_PKG;

Here we've created a package spec which contains only a single DATE variable. Now we'll create a simple body which initializes that variable using a SELECT statement:

CREATE OR REPLACE PACKAGE BODY TEST_PKG IS
  -- package-private variables go first (if any)
(...) 
  -- then the public functions/procedures
(...)
  -- then a final BEGIN-END block which is the package initialization block
BEGIN
  SELECT SYSDATE
    INTO tDATE
    FROM DUAL;
EXCEPTION  -- you can have exception handlers in your initialization block
  WHEN OTHERS THEN
    NULL;  -- pointless here, but this is just an example
    RAISE;
END TEST_PKG;

Now if you execute the following:

begin
  -- Test statements here
  DBMS_OUTPUT.PUT_LINE('TEST_PKG.tDate = ' || TEST_PKG.tDate);
end;

it should print the current date.

Share and enjoy.

like image 159