1

How do I create type methods in PostgreSQL?
Lets take the following type for example:

create type Employee as (
name varchar(20),
salary integer)

How do I do this?

create method giveraise (percent integer) for Employee
begin
set self.salary = self.salary + (self.salary * percent) / 100;
end
5
  • 1
    You do realize that PostgreSQL is SQL database, and not object oriented programming framework? Commented Feb 12, 2013 at 0:08
  • Does that mean that i cant do this in postgres? Commented Feb 12, 2013 at 0:22
  • 2
    Oracle object types can have methods, but I am unaware of a type in Postgres with this behaviour. Instead you would create a function to accept the two parameters: integer and Employee. Commented Feb 12, 2013 at 1:56
  • Unlike Oracle, Postgres does not have type methods. Commented Feb 12, 2013 at 9:01
  • As a side note, what you calculate in your method doesn't make a lot of sense. Would have to be self.salary * ((100::numeric + percent) / 100). Commented Feb 12, 2013 at 9:29

1 Answer 1

3

Postgres doesn't have type methods per se. However, it supports attribute notation for the execution of functions with a single parameter. This looks almost exactly like a method for the type. Consider this simple example:

CREATE OR REPLACE FUNCTION raise10(numeric) 
RETURNS numeric LANGUAGE sql AS 'SELECT $1 * 1.1';

Call:

SELECT (100).raise10;

Result:

 raise10
---------
   110.0

A major limitation is that this only works for a single parameter. No way to pass in additional parameters like a percentage for a variable raise.

Works for composite types just as well. More about "computed fields":

To take this one step further, one can even call an UPDATE on the row and persist the change:

CREATE TABLE employee (
  name text PRIMARY KEY
, salary numeric
);

INSERT INTO employee VALUES 
   ('foo', 100)
 , ('bar', 200)
 ;

CREATE OR REPLACE FUNCTION giveraise10(employee)
  RETURNS numeric
  LANGUAGE sql AS
$func$
UPDATE employee
SET    salary = salary * 1.1   -- constant raise of 10%
WHERE  name = ($1).name
RETURNING salary;
$func$;

Call:

SELECT *, e.giveraise10 FROM employee e;

Result:

 name | salary | giveraise10
------+--------+-------------
 foo  |    100 |       110.0
 bar  |    200 |       220.0

db-fiddle
Old sqlfiddle

SELECT displays the pre-UPDATE value for salary, but the field has actually been updated!

SELECT * FROM employee e;
 name | salary 
------+--------
 foo  |  110.0 
 bar  |  220.0 

Whether it's wise to use such trickery is for you to decide. I probably wouldn't go there. There are more efficient and transparent ways to update a table.

Sign up to request clarification or add additional context in comments.

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.