ToddTheTurtle
ToddTheTurtle

Reputation: 3

How do I write a PLSQL trigger that increments a value?

I just started working with PL/SQL. The database is for a game I want to integrate into my discord bot. Both the DB and the bot are running on Oracle Cloud.

The DB has one table, players, consisting of a discord user id, they have a level initiated with 1, exp initiated with 0 and mana initiated with 100. For now, the first thing I wanted to implement was a TRIGGER that would activate when exp is updated on table players, check if exp reached the level up threshold and if so, reduce exp to 0 and increase the level by 1.

Right now, I have this:

CREATE OR REPLACE trigger level_up
BEFORE UPDATE
ON PLAYERS
FOR EACH ROW
WHEN (:new.EXP >= PLAYERS.LEVEL * 100)
begin
    :new.EXP := 0;
    :new.LEVEL := :old.LEVEL + 1;
end;

When I try to run this, I get the following error: "Error: ORA-00904: : invalid identifier"

Nothing is highlighted and in SQL Developer, when I right-click it and then click "Go to source", it doesn't highlight anything and just throws the cursor to the beginning of the worksheet.

I have already tried a couple different things like

BEFORE UPDATE OF EXP ON PLAYERS

with the rest more or less the same and even tried working with AFTER UPDATE:

CREATE OR REPLACE trigger level_up
AFTER UPDATE
ON PLAYERS
FOR EACH ROW
begin
    UPDATE players
        SET players.exp = 0,
        players.level = players.level + 1
    WHERE players.exp < players.level * 100
end;

This gave me multiple errors though: Error(6,9): PL/SQL: SQL Statement ignored Error(10,5): PL/SQL: ORA-00933: SQL command not properly ended Error(10,8): PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following: ( begin case declare end exception exit for goto if loop mod null pragma raise return select update while with << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge json_exists json_value json_query json_object json_array

At this point I am fully prepared to just abandon the oracle db and switch to mongodb or something, it's just bugging me out that I can't figure out what I am doing wrong.

Thank you for your time!

Upvotes: 0

Views: 55

Answers (1)

Littlefoot
Littlefoot

Reputation: 143143

If the 1st trigger code is OK to you, then just fix what's wrong - why abandoning the whole idea of using Oracle? It's not its (Oracle's fault) you don't know how to use it.

Here's an example.

Table contains just two columns, necessary for this situation.

Column name can't be just level - that's name of a pseudocolumn in hierarchical query and is reserved word for that purpose; I renamed it to c_level (well, you can name it level, but it should then be enclosed into double quotes and you'd have to reference it that way - with double quotes - every time you access it, using exactly the same letter case. In Oracle, that's generally a bad idea).

SQL>  create table players
  2     (exp number,
  3      c_level number
  4    );

Table created.

Trigger: you should have removed colon when referencing the new pseudorecord in the when clause (while in trigger body you have to use it, the colon sign). Also, you don't reference c_level with table's name (players.c_level) but also using the pseudorecord.

SQL> create or replace trigger level_up
  2    before update on players
  3    for each row
  4    when (new.exp >= new.c_level * 100)
  5  begin
  6      :new.exp := 0;
  7      :new.c_level := :old.c_level + 1;
  8  end;
  9  /

Trigger created.

Let's try it. Initial row:

SQL> insert into players (exp, c_level) values (50, 1);

1 row created.

SQL> select * from players;

       EXP    C_LEVEL
---------- ----------
        50          1

Let's update exp so that its value forces trigger to fire:

SQL> update players set exp = 101;

1 row updated.

New table contents:

SQL> select * from players;

       EXP    C_LEVEL
---------- ----------
         0          2

SQL>

If that was your intention, then it kind of works.

Upvotes: 0

Related Questions