I've been working on this project and here is my first function
for step 2. I feel this is the most important one, as I will carry over recommendations from this review into multiple other functions that affect more tables & data.
- Design the DB schema and table relationships, and insert data for standards tables
- Create and test procedures and functions
- Design application behavior
- Design user interface
- Design export methods and formats
One note...
For those who are used to more mainstream RDBMS... PostgreSQL simply doesn't support "procedures", it only has functions. A function can be made to behave like a procedure
and that is what I'm doing here.
Creating the function
set search_path = PsychoProductions;
create or replace function fcn_insert_person(
-- person table
prm_role_id text,
prm_first_name text,
prm_last_name text,
prm_organization text,
prm_website text,
prm_default_billing_method_id text,
prm_active boolean,
-- address table
prm_address_type_id text,
prm_address text,
prm_city text,
prm_state text,
prm_zip_code text,
-- email table
prm_email_address text,
prm_email_type_id text,
-- phone table
prm_phone_number text,
prm_phone_type_id text
)
returns void
language plpgsql
as $$
begin
set search_path = PsychoProductions;
insert into person (
role_id,
first_name,
last_name,
organization,
website,
default_billing_method_id,
active
)
values (
prm_role_id,
prm_first_name,
prm_last_name,
prm_organization,
prm_website,
prm_default_Billing_Method_id,
prm_active
);
insert into address (
person_id,
address_type_id,
address,
city,
state,
zip_code
)
values (
( select currval('person_id_seq') ),
prm_address_type_id,
prm_address,
prm_city,
prm_state,
prm_zip_code
);
insert into email (
person_id,
email_address,
email_type_id
)
values (
( select currval('person_id_seq') ),
prm_email_address,
prm_email_type_id
);
insert into phone (
person_id,
phone_number,
phone_type_id
)
values (
( select currval('person_id_seq') ),
prm_phone_number,
prm_phone_type_id
);
end;
$$
Query returned successfully with no result in 70 ms.
Using the function
A few notes...
The following is a saved template (temporary solution, will be called within an application later). It passes values to the function. I had originally opted to just list the values in the order they are expected, based on the
create function
statement. But then after asking on StackOverflow I found good reasons to explicitly enumerate parameters being passed to the function. So, I opted for the more verbose but less error-proneparameter := value
syntax.I opted for
snake_case
because Postgres silently converts all table, column and function names to lower case. I feel thatprm_default_Billing_Method_id
is better thanprmdefaultbillingmethodid
.Additional note: I used a
function
because I wanted to make sure the whole transaction got processed in one step, inserting data into all 4 tables before it commits.
Executing the function:
set search_path = PsychoProductions;
select fcn_insert_person (
-- person table
prm_role_id := 'Customer',
/*
Staff
Partner
Customer
Vendor
Session musician
*/
prm_first_name := 'firstname',
prm_last_name := 'lastname',
prm_organization := 'organization',
prm_website := 'website',
prm_default_billing_method_id := 'Net 30',
/*
Unassigned
Net 30
Net 15
Cash on delivery
Cash with order
*/
prm_active := True,
-- address table
prm_address_type_id := 'Unique',
/*
Unique
Physical
Shipping
Billing
Mailing
*/
prm_address := 'address',
prm_city := 'city',
prm_state := 'state',
prm_zip_code := 'zip',
-- email table
prm_email_address := 'email',
prm_email_type_id := 'Business',
/*
Business
Personal
*/
-- phone table
prm_phone_number := 'phone',
prm_phone_type_id := 'Mobile'
/*
Mobile
Business
Home
Fax
Pager
*/
);
Total query runtime: 257 ms. 1 row retrieved.
{? = call funcname(?) }
support. Many other RDBMSs support functions as well as procedures. \$\endgroup\$"Double Quote"
your identifiers. \$\endgroup\$RETURNING
clause to capture theperson_id
generated in the firstinsert
, soperson_id
is never defined for later inserts. \$\endgroup\$"Double Quotes"
since it is a PITA to always use those. But if you do think it is best practices, feel welcome to answer the question as such. \$\endgroup\$first_name
andlast_name
! I thought we learned something about doing that. ;) \$\endgroup\$