Postgres Select FOR UPDATE NOWAIT - postgresql

I have a table called account, and I'm selecting a record from this table and I want it to be locked so I'm using UPDATE NOWAIT.
the problem is when I try to insert a record in another table (transaction) which has a foreign key to this table it takes for ever and so I know that it's somehow related to the lock.
Is it the desired functionality ?
Because I'm inserting a record to another table. and the other query might update that record but will not delete it so why not be able to insert a relation?
and what is the solution?

Related

"ON UPDATE" equivalent for Amazon Redshift

I want a create a table that has a column updated_date that is updated to SYSDATE every time any field in that row is updated. How should I do this in Redshift?
You should be creating table definition like below, that will make sure whenever you insert the record, it populates sysdate.
create table test(
id integer not null,
update_at timestamp DEFAULT SYSDATE);
Every time field update?
Remember, Redshift is DW solution, not a simple database, hence updates should be avoided or minimized.
UPDATE= DELETE + INSERT
Ideally instead of updating any record, you should be deleting and inserting it, so takes care of update_at population while updating which is eventually, DELETE+INSERT.
Also, most of use ETLs, you may using stg_sales table for populating you date, then also, above solution works, where you could do something like below.
DELETE from SALES where id in (select Id from stg_sales);
INSERT INTO SALES select id from stg_sales;
Hope this answers your question.
Redshift doesn't support UPSERTs, so you should load your data to a temporary/staging table first and check for IDs in the main tables, which also exist in the staging table (i.e. which need to be updated).
Delete those records, and INSERT the data from the staging table, which will have the new updated_date.
Also, don't forget to run VACUUM on your tables every once in a while, because your use case involves a lot of DELETEs and UPDATEs.
Refer this for additional info.

How to Check if a Foreign Key Exists on a Specific Table in PostgreSQL

I have a foreign key named user__fk__store_id that was supposed to be created on the user table.
However, I made a mistake and instead have it created on another table I have named client.
My servers have an automated process that reads from a JSON file I created with what new tables to create, remove, etc... Every time a server needs to be upgraded with new stuff, it will run through this JSON file and run the queries it needs to.
In this case, in the json file, I'm trying to have it drop the existing incorrect foreign key constraint that was created on the client table, and recreate it correctly on the user table. So technically, it should be running these 2 queries back to back:
ALTER TABLE client DROP CONSTRAINT user__fk__store_id;
ALTER TABLE user ADD CONSTRAINT user__fk__store_id;
The problem I'm having is I can't figure out the query to run in order to see if the user__fk__store_id exists on the client table. I only know how to check if the constraint exists on any table in the database with the following:
SELECT COUNT(1) FROM pg_constraint WHERE conname='user__fk__store_id';
This would be a problem because this means every time I run my upgrade script on my servers, it will always think the constraint of that name already exists, but when it attempts to run the drop query it will error out because it can't find that constraint in the client table.
Is there a query I can run to check not just if the constraint exists, but also if it exists in a specific table?
I found the answer to my own question, I can just run the following query:
SELECT COUNT(1) FROM information_schema.table_constraints WHERE constraint_name='user__fk__store_id' AND table_name='client';
Above answer works fine, but following returns true/false and also checks for schema
SELECT EXISTS (SELECT 1 FROM information_schema.table_constraints
WHERE table_schema='schema_name' AND table_name='MyTable' AND
constraint_name='myTable_fkName_fkey');

postgresql copy from one table to another when the table updates

What I would like is when one row of a table is updated and a new table that will duplicate the original table will update as well but the problem is the original table is a master table that depends on other tables. Any idea how to do this? I'm very new to postgresql.
This is what triggers are for, assuming that the source and destination tables are in the same DB. In this case I think you need an AFTER INSERT OR UPDATE OR DELETE trigger.
http://www.postgresql.org/docs/current/static/plpgsql-trigger.html

Cascade new IDs to a second, related table

I have two tables, Contacts and Contacts_Detail. I am importing records into the Contacts table and need to run a SP to create a record in the Contacts_Detail table for each new record in the Contacts. There is an ID in the Contacts table and a matching ID_D in the Contacts_Detail table.
I'm using this to insert the record into Contacts_Detail but get the 'Subquery returned more than 1 value.' error and I can't figure out why. There are multiple records in Contacts that need have matching records in Contacts_Detail.
Insert into Contacts_Detail (ID_D)
select id from Contacts c
left join Contacts_Detail cd
on c.id = cd.id_d
where id_d is null
I'm open to a better way...
thanks.
It sounds like you're inserting blank child-records into your Contacts_Detail table -- so the first question I'd ask is: Why?
As for why your specific SQL isn't working...
A few things you can check:
Contacts table -- do you have any records there WHERE id is null?
(delete them -- then make the id field a primary key)
Contacts_Detail
table -- do you have any records there WHEERE id_d is null?
(delete them -- then go into your designer and create a relationship
/ enforce referential integrity.)
Verify that c.id is the primary
key, and cd.id_d is the correct foreign key to relate the tables.
Hope that helps
Why not just have a trigger? This seems a little simpler than having to determine for all time which rows are missing - that seems more like something you would do periodically to correct for some anomalies, not something you should have to do after every insert. Something like this should work:
CREATE TRIGGER dbo.NewContacts
ON dbo.Contacts
FOR INSERT
AS
BEGIN
INSERT dbo.Contacts_Detail(ID_D) SELECT ID FROM inserted;
END
GO
But I suspect you have a trigger on the Contacts_Detail table that is not written to correctly handle multi-row inserts, and that's where your subquery error is coming from. Can you show the trigger on Contacts_Detail?

Prevent insertion if the records already exist in sqlite

I am programming for iPhone and i am using SQLITE DB for my app.I have a situation where i want to insert records into the table,only if the records doesn't exist previously.Otherwise the records should not get inserted.
How can i do this?Please any body suggest me a suitable query for this.
Thank you one and all,
Looking at SQLite's INSERT page http://www.sqlite.org/lang_insert.html.
You can do it using the following syntax
INSERT OR IGNORE INTO tablename ....
Example
INSERT OR IGNORE INTO tablename(id, value, data) VALUES(2, 4562, 'Sample Data');
Note : You need to have a KEY on the table columns which uniquely identify a row. It is only if a duplicate KEY is tried to be inserted that INSERT OR IGNORE will not insert a new row.
In the above example if you have a KEY on id, then another row with id = 2 will not be inserted.
If you have a KEY only on id and value then a combination of id = 2 and value = 4562 will cause a new row not be inserted.
In short there must be a key to uniquely identify a ROW only then will the Database know there is a duplicate which SHOULD NOT Be allowed.
Otherwise if you do not have a KEY you would need to go the SELECT and then check if a row is already there, route. But here also whichever condition you are using on columns you can add them as a KEY to the table and simply use the INSERT OR IGNORE
In SQLite it is not possible to ALTER the table and add a constraint like UNIQUE or PRIMAY KEY. For that you need to recreate the table. Look at this FAQ on sqlite.org
http://sqlite.org/faq.html#q11
Hello Sankar what you can do is perform a select query with the record you wish to insert and then check the response via SQLite's SQLITE_NOTFOUND flag you can check whether that record already exists or not. If it doesn't exist you can insert it otherwise you skip inserting.
I hope this is helpful.