Unable to delete a row in postgres db - sql

I am unable to delete a row in postgres db. This is what it shows
candlepin=# delete from cp_upstream_consumer where uuid = 'd88b0079-a271-4ee7-a7fe-ee3a1a7d5';
Cancel request sent
ERROR: canceling statement due to user request
CONTEXT: while locking tuple (0,5) in relation "cp_owner"
SQL statement "SELECT 1 FROM ONLY "public"."cp_owner" x WHERE $1::pg_catalog.text OPERATOR(pg_catalog.=) "upstream_id"::pg_catalog.text FOR KEY SHARE OF x"
This has been hung for several minutes. And after I force quit, It says it has a relation with cp_owner column. But when if we try to delete cp_column, the db may crash. So is there any other way to delete the entry in cp_upstream_consumer table? Since I am new to postgres, I am unable to find out the possible alternatives.
This is what I have in cp_owner table
candlepin=# select * from cp_owner;
id | created | updated | contentprefix | defaultservicelevel | displayname | acco
unt | parent_owner | upstream_id | loglevel | autobind_disabled | content_access_mode | content_access_mode_list | last_refreshe
d | autobind_hypervisor_disabled
----------------------------------+-------------------------------+-------------------------------+---------------+---------------------+-------------+-----
----+--------------+----------------------------------+----------+-------------------+---------------------+--------------------------+---------------------
----------+------------------------------
021308a2752d917a01752d91b05d0001 | 2020-10-16 00:12:03.997+05:30 | 2021-04-16 16:08:32.789+05:30 | /COT/$env | | COT | COT
| | 021308a278d03bc50178da42c1a402bd | | f | entitlement | entitlement | 2021-04-16 16:08:32.
781+05:30 | f
(1 row)
EDIT
After removing couple of postgres process I tried to re-run, and this is the new error when I try to run delete command
candlepin=# delete from cp_upstream_consumer where uuid = 'd88b0079-a271-4ee7-a7fe-ee3a1a7d5';
ERROR: update or delete on table "cp_upstream_consumer" violates foreign key constraint "fk_upstream_consumer_id" on table "cp_owner"
DETAIL: Key (id)=(021308a278d03bc50178da42c1a402bd) is still referenced from table "cp_owner".
Thanks in advance

cp_upstream_consumer has a foreign key to cp_owner, and there is a long running transaction that holds a lock on the referenced row.
Kill the database session that holds the lock, and you can delete the row.

Related

posgresql: relation does not exist

I have ported a database to a new laptop by using an sql dump from the old computer and then executing this dump on the new computer.
Thea data was copied correctly, and all the SQL statements regarding the tables work perfectly.
For creating new relations i need to know the values of some of the sequences in the DB:
italo=> \ds
List of relations
Schema | Name | Type | Owner
--------+--------------------------+----------+-------
public | Conjugation_conjType_seq | sequence | italo
public | Conjugation_idConj_seq | sequence | italo
public | NounItalian_idNounIt_seq | sequence | italo
public | VerbItalian_idVerbIt_seq | sequence | italo
public | times_idTime_seq | sequence | italo
(5 rows)
When i use currval() in a select statement i get an error:
italo=> SELECT currval('VerbItalian_idVerbIt_seq');
ERROR: relation "verbitalian_idverbit_seq" does not exist
LINE 1: SELECT currval('VerbItalian_idVerbIt_seq');
When i look at a sequence in phppgadmin, i get the same error message about the missing relation followed by a column view of the sequence. The error message reads
SQL error:
ERROR: relation "public.verbitalian_idverbit_seq" does not exist
In statement:
SELECT pg_catalog.has_sequence_privilege('public.VerbItalian_idVerbIt_seq','SELECT,USAGE')
Name | Start value | Last value | Increment by | Max value | Min value | Cache value | Log count | Can cycle? | Will increment last value before returning next value (is_called)?
VerbItalian_idVerbIt_seq | 100 | | 1 | 9223372036854775807 | 1 | 1 | | No | No
Alter Set value Increment value Restart Reset Show all sequences
(the values for "Last value" and "Log count" are empty)
When i click on "Set value", i can enter a value for "Last value", and there is small message "Sequence value set.", but in the view nothing has changed.
The behavior is the same for all 5 sequences.
What do i have to do to fix my sequences so that i can use currval() on them?
EDIT: when i create a new sequence from scratch, it behaves as expected
Because of the usage of UpperCase characters, you have to use double quotes " around the identifiers:
SELECT currval('"VerbItalian_idVerbIt_seq"');

How to dump selected PostgreSQL data from one database to other databse

I have three tables with foreign key relationship with each other.
The table school will be uploaded manually. A student will login to the website and check their marks
The entire data is to be uploaded to another new database of different instance
The Login Id(stud_id) of the student in DB1 is 10 and Login Id(stud_id) of the student in DB2 is 1 in another instance.
For retaining the data of student_marks table, I intend to do the following steps,
1. Dump student_marks table from DB1
2. Copy it to DB2
NOTE: stud_id would be different for both the databases
Is there any way to do the above.
Refer the table below,
school:
id | name| place
-----+-------------
1 | sch1 | test
student:
id | school_id| stud_name
-----+-------------
1 | 1 | stud1
student_marks:
id | stud_id| subj1 | subj2
-----+-----------------------
1 | 1 | 30 | 30
Thanks in advance!
First Disable the foreign key constraint, then dump the data and after that again enable the foreign key constraint or you can put foreign key constraint after migrating the data.

Getting difference from two tables and deleting it in SQL Server

I am facing issue in writing the logic of a query that deletes data which are not existing in either of the 2 tables.
For example, I have a tables "Stage" and "Parent". I am using composite primary keys to uniquely identity records(multiple primary keys).
Stage structure and Data
S_Column1(Primary) | PRIDATA1 | PRIDATA4
S_Column2(Primary) | PRIDATA2 | PRIDATA5
S_Column3(Primary) | PRIDATA3 | PRIDATA6
S_Column4 | DJUC | JDNC
S_Column5 | DSSDC | JDDOS
Parent structure and Data
P_Column1(Primary) | PRIDATA1 | PRIDATA4 | PRIDATA7
P_Column2(Primary) | PRIDATA2 | PRIDATA5 | PRIDATA8
P_Column3(Primary) | PRIDATA3 | PRIDATA6 | PRIDATA9
P_Column4 | DJUC | JDNC | FFED
P_Column5 | DSSDC | JDDOS | NHUY
The above is just a sample of structure and data of two tables.
So basically what I want to do is write a query to delete the row that have
PRIDATA7 PRIDATA8 and PRIDATA9 as primary key because their entries are not present in STAGE TABLE.
I am not skilled, but I know I need to find out matching data using JOIN and delete the rest of the data from PARENT TABLE whose entries aren't present in STAGE TABLE
PS: I will be using this in a Trigger.
Try not exists
delete from parent
where not exists (
select 1
from stage s
where s.S_Column1 = parent.S_Column1 and s.S_Column2 = parent.S_Column2 and s.S_Column3 = parent.S_Column3)
You might be looking for the EXCEPT operator.
Read here: https://msdn.microsoft.com/pl-pl/library/ms188055(v=sql.110).aspx

How to lock a table when selecting records return no data

Consider this table:
| id | objId | fieldNumber |
|------|-------|-------------|
| 902 | 1 | 1 |
| 908 | 1 | 2 |
| 1007 | 1 | 3 |
| 1189 | 8 | 1 |
| 1233 | 12 | 1 |
| 1757 | 15 | 1 |
I want to enter a new record for a non existant obj. Lets say objId: 16. The field number must increase by 1 for every obj 16. Take a look at obj: 1. As you can see it increases by 1. Now if two or more database connections try to insert obj 16 at the same time I would have two obj 16 with fieldNumber 1. This cannot happen. I must guarantee the field numbers are not the same and must increase by one.
So my solution is get all records by objid. If there is at least one record then place a lock on all records by that objid then insert a record with the next fieldNumber.
Alternatively, when I get all records by objid. If there are no records then I will lock the whole table then insert a record with fieldNumber 1.
How would I go about placing a lock on the whole table? Let me know if you have a better idea to do this?
If you can handle exceptions, then probably the easiest way is to add a unique constraint on (objid, fieldnumber).
Then you can run a query, such as:
insert into t(objid, fieldnumber)
select #objid, coalesce(max(fieldnumber) + 1, 1)
from t
where objid = #objid;
If two simultaneous threads attempt to run the query, then the unique constraint will fail -- and the thread can re-try.
You can also use the SERIALIZABLE table hint (which is explained here).
It seems that objId and fieldNumber together (should) form the primary key for this table. Normalized that way the constraint would be automatically enforced. I think this is a 'cleaner' solution. But if you can't drop an autonumbering PK scheme, then Gordon's solution is unbeatable.

How can I link my Junction table to my main table

I have a SQL database with the main table called Results. This table stores a record of results of tests that are run nightly.
The Results table has many fields but for arguments say lets just say for now it looks like this:
ResultID (Unique key field generated upon insert)
Result (nvchar10)
What I wanted to be able to record was a list of tags used in the tests that were run. The tags may be different for each result and an array of them are stored.
I created a junction table as shown below called Tags:
TagID (int key field unique generated at runtime)
ResultID (int)
ScenarioTag (nvchar128)
FeatureTag (nvchar128)
So what im looking to do is to link these 2 together. I'm not so great with databases ill be honest.
I was thinking that when I save the test results with my normal SQL query immediately after I would loop through each tag and save the tags to this new table but maybe i'm wrong here?
Psuedocode:
//Returned from previous SQL statement that inserted results values into the DB
int ResultID = SQLQueryReturnValue;
Foreach TAG in TAGS
{
string SQLQuery = "INSERT INTO TAGS (ResultID, ScenarioTag, FeatureTag)(#ResultID, #ScenarioTag, #FeatureTag)";
CmdSql.Parameters.AddWithValue("#ResultID", ResultID);
CmdSql.Parameters.AddWithValue("#ScenarioTag", TAG.Scenario);
CmdSql.Parameters.AddWithValue("#FeatureTag", TAG.Feature);
CmdSql.CommandText = SQLQuery;
CmdSql.Execute();
}
Heres an example of what each table might actually look like:
Results Table
|ResultID | Result |
| 10032 | Pass |
| 10031 | Fail |
| 10030 | Fail |
Tags Table
| TagID | ResultID | ScenarioTag | FeatureTag |
| 6 | 10032 | Cheque | Trading |
| 5 | 10032 | GBP | Sales |
| 4 | 10031 | Direct Credit | Trading |
| 3 | 10031 | GBP | Purchase |
| 2 | 10030 | Wire | Dividends |
| 1 | 10030 | USD | Payments |
So finally onto my question...Is there a way that I can physically link this new "Tags" table to my results table. Its informally linked in a way using the ResultID but theres no physical link.
Is it this you're looking for? (Assumption: This query is looking from results. They do not necessarily have to have Tags...)
SELECT *
FROM Results
LEFT JOIN Tags ON Results.ResultID=Tags.ResultID
EDIT: Maybe I did not understand, what you mean by "physically". You could add a foreign key constraint:
ALTER TABLE Tags ADD CONSTRAINT FK_Tags_Results FOREIGN KEY (ResultID) REFERENCES Results(ResultID);
This constraint adds a relation to these tables, making sure, that only values existing in Results are allowed in Tags as "ResultID". On the other hand you cannot delete a Result row with existing children in Tags...
If you do this you could alter the top query to:
SELECT *
FROM Tags
INNER JOIN Results ON Results.ResultID=Tags.ResultID
Now you are looking from Tags (leading table) and you know, that each tag must have a ResultID (INNER JOIN).