text[] in postgresql? - postgresql

I saw a field text[] (text array) in Postgresql.
As far as I understood,it can store multiple text data in a single column.
I tried to read more about it the manual: http://www.postgresql.org/docs/current/static/datatype-character.html but unfortunately nothing much was there about text[] column type.
So can anyone help me to understand
How to add a new value to text[] column?
What will be the resultset when we query to retrieve the values of text[] column?
EDIT
I have a table containing 2 columns group_name and members. Each time a new person join the group,the new person's id should be inserted in the column members for that group_name. This is my requirement.A Group can contain 'n' number of members
EDIT 2
Pablo is asking me to use two tables instead. May I know how this could be solved by using two different tables? Right now I am using comma(,) to store multiple values separated by comma. Is this method wrong?

To insert new values just do:
insert into foo values (ARRAY['a', 'b']);
Assuming you have this table:
create table foo (a text[]);
Every time you do a select a from foo you will have a column of type array:
db1=> select a from foo;
a
-------
{a,b}
(1 row)
If you want a specific element from the array, you need to use subscripts (arrays in PostgreSQL are 1-based):
db=> select a[1] from foo;
a
---
a
(1 row)
Be careful when choosing an array datatype for your PostgreSQL tables. Make sure you don't need a child table instead.

Related

insert function with side-effects: how to take insert parameter?

I'm interested in writing a Postgres function that inserts a new row to e.g. an invoice table, and performs some side effects based on the result of the insertion. My invoice table has some columns with default values (e.g. auto-generated primary key column id), and some that are optional.
I'm wondering if there's a way to take a parameter that represents a row of the invoice table, possibly without default and optional fields, and insert that value directly as a row.
CREATE OR REPLACE FUNCTION public.insert_invoice(new_invoice invoice)
RETURNS uuid
LANGUAGE sql
AS $$
WITH invoice_insert_result AS (
-- This fails: new_invoice has type invoice, but expected type uuid (because it thinks we want to put `new_invoice` in the "id" column)
INSERT INTO invoice VALUES (new_invoice)
RETURNING id
)
-- Use the result to perform side-effects
SELECT invoice_insert_result.id
$$;
I know this is possible to do by replicating the schema of the invoice table in the list of parameters of the function, however I'd prefer not to do that since it would mean additional boilerplate and maintenance burden.
The uuid is a value that is automatically generated, you cannot insert a uuid value to a table.
The target column names can be listed in any order. If no list of
column names is given at all, the default is all the columns of the
table in their declared order; or the first N column names, if there
are only N columns supplied by the VALUES clause or query. The values
supplied by the VALUES clause or query are associated with the
explicit or implicit column list left-to-right.
https://www.postgresql.org/docs/current/sql-insert.html
The quote part means that you insert command can either explicit mention column list. Or you not mention column list then the to be inserted command (after values) should have all the column list's value.
to achiever your intended result, Insert command,you must specify columns list. If not, then you need insert uuid value. But you cannot uuid is auto generated. The same example would be like if a table have a column bigserial then you cannot insert bigserial value to that column. Since bigserial is auto-generated.
For other non-automatic column, You can aggregated them use customized type.
denmo
create type inv_insert_template as (receiver text, base_amount numeric,tax_rate numeric);
full function:
CREATE OR REPLACE FUNCTION public.insert_invoice(new_invoice inv_insert_template)
RETURNS bigint
LANGUAGE sql
AS $$
WITH invoice_insert_result AS (
INSERT INTO invoices(receiver,base_amount, tax_rate)
VALUES (new_invoice.receiver,
new_invoice.base_amount,
new_invoice.tax_rate) RETURNING inv_no
)
SELECT invoice_insert_result.inv_no from invoice_insert_result;
$$;
call it: select * from public.insert_invoice(row('person_c', 1000, 0.1));
db fiddle demo

How do you get a list of tables name that contains a specific column name on Firebird?

I have to find a table (or more than one) that contains a column named 'idRec' on a Firebird database.
You can query the RDB$RELATION_FIELDS table for this:
select RDB$RELATION_NAME
from RDB$RELATION_FIELDS
where RDB$FIELD_NAME = 'idRec'
This will only match columns that are actually called idRec (and thus are required to be quoted when used in SQL statements). If you are actually looking for a column called IDREC (unquoted object names are stored in uppercase), use where RDB$FIELD_NAME = 'IDREC'

PGSQL - Change all columns of a specific datatype to text

I'm trying to change all the USER-DEFINED columns to TEXT in a specific view using pgsql.
Is it possible to do that in a single alter table query ou do I need to check first what columns contain that dataype and then perform the dataype change one by one?
This is what I'm trying:
ALTER TABLE if exists "schemaName"."Table_A"
ALTER COLUMN (
select column_name
from information_schema.columns inf
where table_name = 'Table_A' and inf.data_type = 'USER-DEFINED')
TYPE TEXT;
I'm getting and error in the subquery start "("
You need to do this one by one. Generally speaking such DDL statements cannot work on several objects in one statement.
For ALTER TABLE, see: https://www.postgresql.org/docs/12/sql-altertable.html.
FOR ALTER VIEW, see: https://www.postgresql.org/docs/current/sql-alterview.html

Compute shared hstore key names in Postgresql

If I have a table with an HSTORE column:
CREATE TABLE thing (properties hstore);
How could I query that table to find the hstore key names that exist in every row.
For example, if the table above had the following data:
properties
-------------------------------------------------
"width"=>"b", "height"=>"a"
"width"=>"b", "height"=>"a", "surface"=>"black"
"width"=>"c"
How would I write a query that returned 'width', as that is the only key that occurs in each row?
skeys() will give me all the property keys, but I'm not sure how to aggregate them so I only have the ones that occur in each row.
The manual gets us most of the way there, but not all the way... way down at the bottom of http://www.postgresql.org/docs/8.3/static/hstore.html under the heading "Statistics", they describe a way to count keys in an hstore.
If we adapt that to your sample table above, you can compare the counts to the # of rows in the table.
SELECT key
FROM (SELECT (each(properties)).key FROM thing1) AS stat
GROUP BY key
HAVING count(*) = (select count(*) from thing1)
ORDER BY key;
If you want to find the opposite (all those keys that are not in every row of your table), just change the = to < and you're in business!

Inserting multiple records and updating identity column in SQL

i have to insert multiple records into a table and in the mean time needed to insert the identity column of the first table in to another table.Can i do it avoiding loop?
Edited
i have two tables named StudentMaster and StudentSujects.
First Table structure is (StudentID int Identity(1,1),StudentName varchar(100))
Second table structure is (SubjectID int Identity(1,1),StudentID int,SubjectName varchar(100)).
StudentID in the 'StudentSujects' table is the Identity column of first table 'StudentMaster'.
INSERT INTO StudentMaster
(
StudentName
)
SELECT StudentName
FROM OPENXML(#hDoc,'/XML/Students')
WITH( StudentName varchar(100) 'StudentName')
I am inserting multiple records in to the first table using the above query.I the mean time i have to insert the identity column of each row in to the second table.
You can use the OUTPUT clause to output multiple columns/rows on an INSERT operation into a table variable.
Assuming your table that you're inserting into has an IDENTITY column called ID, you could have code something like this:
DECLARE #InsertedData TABLE (NewID INT, SomeOtherColumn.....)
INSERT INTO dbo.YourTable(Col1, Col2, ..., ColN)
OUTPUT INTO #InsertedData(NewID, SomeOtherColumn) Inserted.ID, Inserted.OtherColumn
VALUES(Val11, Val12, ..., Val1N),
(Val21, Val22, ..., Val2N),
....
(ValM1, ValM2, ..., ValMN)
Of course, you need to have something that allows you to identify which row in your second table to insert which value into - that's entirely dependent on your situation (and you didn't offer any explanation of that in your question).
But basically, using the OUTPUT clause, you can capture as much information as you need, including the newly assigned IDENTITY values, so that you can then do your second insert based on that information.