insertion of nested array of custom in table for postgres - postgresql

command = (
CREATE TYPE belongings AS (
item TEXT,
quantity INTEGER
)
CREATE TYPE student AS (
name TEXT,
id INTEGER,
bag belongings[]
)
CREATE TABLE studentclass(
date DATE NOT NULL,
time TIMESTAMPTZ NOT NULL,
PRIMARY KEY (date, time),
class student
)
)
Can i ask how to do insert for this in postgres psycog2? thank you.
When i put the insert as
insert_sql = "INSERT INTO studentclass (date, time, class) VALUES (%s,%s,%s)"
error output is
DETAIL: Cannot cast type text[] to belongings[] in column
I don't think i just cast it with "::belongings[]" in the INSERT statement as it is a nested.
My earlier asked question for a simpler table.
Unable to insert nested record in postgres

Related

Running A FOREACH after a CTE in a PostgreSQL procedure?

I have a PLPGSQL procedure that:
A) Inserts an employee into an Employee table.
B) Also insert the generated serial eid into another Manager table.
C) Finally, the procedure also dictates an array of course_areas that I would like to insert in a specialize table.
Procedure where C and D array are the course_areas
CALL add_employee('Athena', '22222222', 'athena#outlook.com', '2012-12-12', '111', 'instructor', 300.0, NULL,
'{C,D}'::text[]);
Employees
CREATE TABLE Employees (
eid SERIAL PRIMARY KEY,
name TEXT NOT NULL,
phone TEXT NOT NULL,
email TEXT NOT NULL,
join_date DATE NOT NULL,
address TEXT NOT NULL,
depart_date DATE
);
Managers
CREATE TABLE Managers (
eid INT PRIMARY KEY,
monthly_salary DECIMAL(10,2) NOT NULL,
FOREIGN KEY (eid) REFERENCES Employees(eid)
ON DELETE CASCADE
);
Specializes
CREATE TABLE Specializes (
eid INT NOT NULL,
name TEXT NOT NULL,
PRIMARY KEY (eid, name),
FOREIGN KEY (eid) REFERENCES Employees(eid)
on DELETE CASCADE,
FOREIGN KEY (name) REFERENCES Course_areas(name)
on DELETE CASCADE
);
procedure.sql
CREATE OR REPLACE PROCEDURE add_employee (name TEXT, phone TEXT, email TEXT, joinDate DATE, address TEXT, category TEXT, monthlySalary DECIMAL(10,2) default NULL, hourlySalary DECIMAL(10,2) default NULL, courseAreas TEXT[] default NULL)
...
WITH FIRST AS (
INSERT INTO Employees(
name, phone, email, join_date, address
)
VALUES
(
name, phone, email, joinDate, address
) RETURNING eid
),
SECOND AS (
INSERT INTO Full_time_instructors(eid, monthly_salary)
SELECT
eid,
monthlySalary
FROM
ROWS RETURNING eid
)
FOREACH area IN ARRAY courseAreas
LOOP
RAISE NOTICE '%', area; -- should print "C" and "D"
END LOOP;
Error
ERROR: syntax error at or near "FOREACH"
LINE 27: FOREACH area IN ARRAY courseAreas
I can get A) and B) to work.
How can I use FOREACH to iterate through my courseAreas that I pass to the procedure such that I can insert each course area and the eid into a Specialize table?
The FOREACH is a PLPGSQL control structure whereas the CTE is a SQL feature. You can't mix these. Instead of using CTE you can simply perform the first statement, using the RETURNING clause to retrieve the eid to a local variable. You can then use this variable with the subsequent statement and inside your FOREACH loop.
This question gives an overview of getting the new serial value using returning: Get default serial value after INSERT inside PL/pgSQL.

How to insert and then update returned Id from insert query as returning id in a single command in postgres?

I have a demo table
CREATE TABLE items (
id SERIAL primary key,
user_id integer,
name character varying,
created timestamp with time zone default now()
);
And I want a single query to run and first insert data, then return primary key using returning id and then update the same table with the returned id.
INSERT INTO items (name) values ('pen') RETURNING id as idd
update items set user_id=(select idd) where id=(select idd)
but the above command doesn't work and throws syntax error.
Any help will be appriciated.
You can do that right within the INSERT statement:
INSERT INTO items
(name, user_id)
values
('pen', currval(pg_get_serial_sequence('items','id')));
Online example
You can try this way also :
create temp table insert_item as
with insert_item_cte as (
INSERT INTO items (name)
values ('pen') returning id
)
select id from insert_item_cte;
update items set user_id = items.id
from insert_item ii
where ii.id = items.id;
Online Demo

How to select last value insert in column ( like function LAST() for OracleDB)

I'm actually sutend and I'm setting up DB PostgreSQL for my AirsoftShop and some request on it. I need to find similar function as SELECT LAST(xx) FROM yy usable on SQL server and OracleDB i think. For return the last insert values in the column target by LAST().
I have this table :
CREATE TABLE munition.suivi_ammo (
type_ammo integer NOT NULL,
calibre integer NOT NULL,
event integer NOT NULL,
date_event date NOT NULL,
entrance integer NOT NULL,
exit integer NOT NULL,
inventory integer NOT NULL,
FOREIGN KEY (calibre) REFERENCES munition.index(numero),
FOREIGN KEY (event) REFERENCES munition.index(numero),
FOREIGN KEY (type_ammo) REFERENCES munition.index(numero)
);
and index for definition by number id :
CREATE TABLE munition.index (
numero integer NOT NULL,
definition text NOT NULL,
PRIMARY KEY (numero)
);
I want to select the last inventory insert in the table and calculate the current inventory according to the inflow and outflow made after my inventory
It's works when i do this type of request with specific date to be sure to only have the last one inventory, but I do not want to have to do it
SELECT index.definition,
Sum(suivi_ammo.inventory) + Sum(suivi_ammo.entrance) - Sum(suivi_ammo.exit) AS Stock
FROM munition.suivi_ammo
INNER JOIN munition.index ON suivi_ammo.type_ammo = index.numero
WHERE date_event < '03/05/2019' AND date_event >= '2019-04-10'
GROUP BY index.definition;
I also tried to used last_value() window function but doesn't work.
Thx !

Access database, Sql query , Error "Syntax error in DROP TABLE or DROP INDEX."

This is the query , running this in C#.
n getting above error
"DROP TABLE IF EXISTS `NATIONAL_ID_ISSUANCE_CENTER`;
CREATE TABLE `NATIONAL_ID_ISSUANCE_CENTER` (
`ID` INTEGER NOT NULL AUTO_INCREMENT,
`NAME` VARCHAR(100),
`APPLICATION_ID` INTEGER,
`STATUS` INTEGER,
`CREATED_BY` INTEGER,
`UPDATED_BY` INTEGER,
`CREATED_DATE` DATETIME,
`UPDATED_DATE` DATETIME,
`THIRD_PARTY_ID` INTEGER,
`PROVINCE_ID` INTEGER,
INDEX (`APPLICATION_ID`),
PRIMARY KEY (`ID`),
INDEX (`PROVINCE_ID`),
INDEX (`THIRD_PARTY_ID`)
)"
You can't put an IF statement inside Drop and Create statements. Anytime you want to drop a table that you're not sure exists, use the following:
IF(OBJECT_ID('[Database].[Schema].[TableName]') is not null)
BEGIN
DROP TABLE [Database].[Schema].[TableName];
END;
Please note you should replace [Database], [Schema], and [TableName] with the appropriate database, schema, and table names, respectively.

insert string into text [] column

I have the following issue.
I will receive input as a text from a webservice to insert into a certain psql table. assume
create table test ( id serial, myvalues text[])
the recieved input will be:
insert into test(myvalues) values ('this,is,an,array');
I want to create a trigger before insert that will be able to convert this string to a text [] and insert it
first Idea that came in my mind was to create a trigger before insert
create function test_convert() returns trigger as $BODY%
BEGIN
new.myvalues = string_to_array(new.myvalues,',')
RETURNS NEW
END; $BODY$ language plpgsql
but this did not work
You can use the string_to_array function to convert your string into an string array within your insert query:
INSERT INTO test ( myvalues )
VALUES ( string_to_array( 'this,is,an,array', ',' ) );
Suppose you receive text in the following format this is an array and you want to convert it to this,is,an,array then you can use string_to_array('this is an array', ' ') and it will be converted. However if you are receiving comma separated then you can just used it.
Creating the Table Schema Like this,
CREATE TABLE expert (
id VARCHAR(32) NOT NULL,
name VARCHAR(36),
twitter_id VARCHAR(40),
coin_supported text[],
start_date TIMESTAMP,
followers BIGINT,
PRIMARY KEY (id)
);
Inserting values like this will help you to insert array,
insert into expert(id, name, twitter_id, coin_supported, start_date, followers) values('9ed1cdf2-564c-423e-b8e2-137eg', 'dev1', 'dev1#twitter', '{"btc","eth"}', current_timestamp, 12);