0

I have a little DB with 3 tables: account, account_statements and account operations. I need to know:

  1. all credit operations of the period

  2. all debet operations of the perion

  3. a balance on any date

My script is:

    CREATE TABLE account 
(
   id number(10) NOT NULL,
   account number(20) NOT NULL,
   CONSTRAINT account_id PRIMARY KEY (id)
);


CREATE TABLE account_statements
(
   id number(10) NOT NULL,
   account_id number(10) NOT NULL,
   statement_date date,
   inbalance number(20,2),
   outbalance number (20,2),
   CONSTRAINT statement_id PRIMARY KEY (id),
   CONSTRAINT account_statements_foreign_id FOREIGN KEY (account_id) REFERENCES account(id)
);


CREATE TABLE account_operations
(
   id number(10) NOT NULL,
   account_id number(10) NOT NULL,
   operdate date,
   summ number(20,2),
   opertype char(6),
   CONSTRAINT operations_id PRIMARY KEY (id),
   CONSTRAINT account_operations_foreign_id FOREIGN KEY (account_id) REFERENCES account(id)
);

CREATE OR REPLACE FUNCTION Get_debet_on_period (
   v_startdate IN date,
   v_enddate IN date,
   v_account IN account.account%TYPE)
RETURN number
IS
   v_debet_summ number(20,2);
BEGIN
   SELECT SUM(summ) INTO v_debet_summ
   FROM account_operations ao,
      account a
   WHERE ao.operdate between v_startdate AND v_enddate
      AND ao.opertype='DEBET'
      AND a.account=v_account
      AND ao.account_id=a.id;

    RETURN v_debet_summ;
END;

CREATE OR REPLACE FUNCTION Get_credit_on_period (
   v_startdate IN date,
   v_enddate IN date,
   v_account IN account.account%TYPE)
RETURN number
IS
   v_credit_summ number(20,2);
BEGIN
   SELECT SUM(summ) INTO v_credit_summ
   FROM account_operations ao,
      account a
   WHERE ao.operdate between v_startdate AND v_enddate
      AND ao.opertype='CREDIT'
      AND a.account=v_account
      AND ao.account_id=a.id;
    RETURN v_credit_summ;
END;

CREATE OR REPLACE FUNCTION Get_balance_on_date (
   v_date IN date,
   v_account IN account.account%TYPE)
RETURN number
IS 
   v_balance_summ number(20,2);
   v_startdate date; 
   v_startsumm number;
BEGIN
   SELECT MAX(as.statement_date) INTO v_startdate
   FROM account_statements as, account a
   WHERE a.id=as.account_id
   AND a.account=v_account
   AND as.statement_date<v_date;
   IF v_startdate IS NOT NULL THEN
      SELECT as.outbalance INTO v_startsumm
      FROM account_statement as, account a
      WHERE a.id=as.account_id
      AND a.account=v_account
      AND as.statement_date=v_statement_date;
      v_balance_summ:=v_startsumm+Get_credit_on_period(v_startdate, v_date, v_account)-Get_debet_on_period(v_startdate, v_date, v_account);
    ELSE
      v_startsumm:=0;
      v_balance_summ:=Get_credit_on_period(v_startdate, v_date, v_account)-Get_debet_on_period(v_startdate, v_date, v_account);
    END IF;

   RETURN v_balance_summ;
END;

I have an error in function Get_balance_on_date:

Errors: FUNCTION GET_BALANCE_ON_DATE Line/Col: 10/4 PL/SQL: SQL Statement ignored Line/Col: 10/15 PL/SQL: ORA-00936: missing expression Line/Col: 16/7 PL/SQL: SQL Statement ignored Line/Col: 16/14 PL/SQL: ORA-00936: missing expression

2 Answers 2

2

Your function get_balance_on_date does not compile.

  1. You're using table account_statement, however you created table named in plural form account_statements.
  2. You're using reserved keyword AS as an alias "account_statements as". You should change the alias to something different.
  3. You're using undeclared variable "v_statement_date".

Fixed function for you:

CREATE OR REPLACE FUNCTION get_balance_on_date
(
    v_date    IN DATE
   ,v_account IN account.account%TYPE
) RETURN NUMBER IS
    v_balance_summ NUMBER(20, 2);
    v_startdate    DATE;
    v_startsumm    NUMBER;
    v_statement_date DATE; -- Remove this if you don't need, created this for function to compile
BEGIN
    SELECT MAX(stm.statement_date)
      INTO v_startdate
      FROM account_statements stm
          ,account            a
     WHERE a.id = stm.account_id
       AND a.account = v_account
       AND stm.statement_date < v_date;

    IF v_startdate IS NOT NULL
    THEN
        SELECT stm.outbalance
          INTO v_startsumm
          FROM account_statements stm
              ,account           a
         WHERE a.id = stm.account_id
           AND a.account = v_account
           AND stm.statement_date = v_statement_date;

        v_balance_summ := v_startsumm +
                          get_credit_on_period(v_startdate, v_date, v_account) -
                          get_debet_on_period(v_startdate, v_date, v_account);
    ELSE
        v_balance_summ := get_credit_on_period(v_startdate, v_date, v_account) -
                          get_debet_on_period(v_startdate, v_date, v_account);
    END IF;

    RETURN v_balance_summ;
END;
Sign up to request clarification or add additional context in comments.

Comments

1

You are using a reserved keyword as an alias

FROM account_statements as, account a

as has to be changed to something else since it is part of the SQL language.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.