Describe table to get the primary key for a table in Apache Derby - primary-key

I am using Apache Derby 10.14.2. I need to know the primary key for a table. When I perform the Describe for the table, I only got the following instruction.
derby system tables for the column of primary key info do not have an answer.
ij> create table id ( id int primary key, name varchar(10));
ij> describe id;
COLUMN_NAME |TYPE_NAME|DEC&|NUM&|COLUM&|COLUMN_DEF|CHAR_OCTE&|IS_NULL&
------------------------------------------------------------------------------
ID |INTEGER |0 |10 |10 |NULL |NULL |YES
NAME |VARCHAR |NULL|NULL|10 |NULL |20 |YES
In this, no information about the primary key is given. What is the query to get the primary key of a table in Apache Derby?

In a program, use DatabaseMetaData.getPrimaryKeys()
Or, if you want to run queries against the Derby system catalogs directly, you can read the answers to this related question.

Related

Row not created but increments primary key

I am attempting to insert new rows into the following PostgreSQL table:
Table "public.users"
Column | Type | Collation | Nullable | Default
---------------+--------------------------+-----------+----------+----------------------------------------------
user_id | integer | | not null | nextval('define_user_user_id_seq'::regclass)
time_created | timestamp with time zone | | not null |
is_active | boolean | | not null | true
email_address | text | | not null |
password_hash | character varying(255) | | not null |
first_name | text | | |
second_name | text | | |
Indexes:
"users_pkey" PRIMARY KEY, btree (user_id)
Referenced by:
TABLE "user_to_device" CONSTRAINT "user_to_device_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(user_id)
TABLE "user_to_horse" CONSTRAINT "user_to_horse_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(user_id)
The table currently only contains 10 records as it is still being used for development. There is no scope to modify the table.
My issue is that, when updating the table from a REST API the operation seemingly successfully and returns a new user_id; upon querying the table, the supposedly created user is not in the table.
If I then create a user manually (SSH'd into the server that's running psql) and use the exact same query then the operation is successful and the newly created user can be seen. Interestingly, the user_id value increments from the value created by the query triggered by the REST API.
This suggests to me that the query triggered via the REST API is successful (?) because the user_id that it creates seems to be recognised by subsequent queries - so why then does the new user not appear in the table?
No errors are thrown at all. Here's the query that I'm using to create a user:
INSERT INTO users (password_hash, is_active, first_name, email_address, second_name, time_created) VALUES ('mypasswordhash', True, 'Orson', 'user#example.com', 'Cart', '2018-11-23T12:23:00Z') RETURNING user_id;
I am using psycopg2 from within Python 3.6 when querying via the API. I have multiple other API endpoints that INSERT successfully into other tables so I'm not sure at all what the issue is. Any help is greatly appreciated as this has me truly stumped, thanks.
Are you absolutely sure
your commit function is called?
In some cases
if you yield or return
before committing,
the function is aborted
before your changes get committed.
In this case, I would expect to see
an incremented ID without an inserted row,
as primary keys get incremented
before the query is checked.
If your connection terminates abruptly,
the row won't get committed.
Your best bet would be to
examine your PostgreSQL server logs.

drop primary key constraint in postgresql by knowing schema and table name only

As far I know the only way of dropping primary key in postgresql is:
ALTER TABLE schema.tableName DROP CONSTRAINT constraint_name;
the constraint name by default is tableName_pkey. However sometimes if table is already renamed I can’t get the original table name to construct right constraint name.
For example, for a table created as A then renamed to B the constraint remains A_pkey but I only have the table name B.
Do you know right way to drop the pkey constraint by knowing only the schema name and table name ?
I am writing program for doing this so I need to use only SQL queries. Solutions like "open pgAdmin and see the constraint name" will not work.
You can use information from the catalog tables like so:
Create a table with id as the primary key
create table test1 (id int primary key, name text);
Create the SQL to drop the key
select concat('alter table public.test1 drop constraint ', constraint_name) as my_query
from information_schema.table_constraints
where table_schema = 'public'
and table_name = 'test1'
and constraint_type = 'PRIMARY KEY';
The result will be:
alter table public.test1 drop constraint test1_pkey
You can create a stored function to extract this query and then execute it.
login to the database using psql, the command line tool.
Then type:
\d <table_name>
for example:
\d claim
Table "public.claim"
Column | Type | Collation | Nullable | Default
--------------------------------+-----------------------------+-----------+----------+-----------------------------------
id | integer | | not null | nextval('claim_id_seq'::regclass)
policy_id | integer | | |
person_id | integer | | |
incident_id | integer | | |
first_notification_of_loss | timestamp without time zone | | |
police_reference | character varying(40) | | |
photos_to_follow | boolean | | |
sketch_to_follow | boolean | | |
description_of_weather | character varying(2000) | | |
description_of_property_damage | character varying(2000) | | |
created_at | timestamp without time zone | | not null | now()
updated_at | timestamp without time zone | | not null |
Indexes:
"primary_key_claim" PRIMARY KEY, btree (id)
Foreign-key constraints:
"foreign_key_claim_incident" FOREIGN KEY (incident_id) REFERENCES incident(id)
"foreign_key_claim_person" FOREIGN KEY (person_id) REFERENCES person(id)
"foreign_key_claim_policy" FOREIGN KEY (policy_id) REFERENCES policy(id)
Referenced by:
TABLE "claimant" CONSTRAINT "foreign_key_claimant_claim" FOREIGN KEY (claim_id) REFERENCES claim(id)
TABLE "damage" CONSTRAINT "foreign_key_damage_claim" FOREIGN KEY (claim_id) REFERENCES claim(id)
TABLE "witness" CONSTRAINT "foreign_key_witness_claim" FOREIGN KEY (claim_id) REFERENCES claim(id)
This shows you the primary key name (as well as other stuff).
If you want to do this programmatically and you are using Java or another language that uses the JDBC interface, you can use the class DatabaseMetaData, method getPrimaryKeys.
Otherwise, the other answer, selecting from the system catalogs, is the way to go.
For those using PGAdmin:
Navigate to the Database>Schemas>{your schema}>Tables>{your table name} right-click>Properties.
Go to the Constraints tab and add/remove at will.
I did this using PGAdmin 4 and PostgreSQL 14.

save() cannot change primary key, it's a bug?

I wanna change the primary key in one table, but phalcon seems not offer any method to change the primary key.
uid is primary key in this table
+----+------------+------------+------+
| uid | name | type | year |
+----+------------+------------+------+
| 1 | Robotina | mechanical | 1972 |
| 2 | Astro Boy | mechanical | 1952 |
| 3 | Terminator | cyborg | 2029 |
+----+------------+------------+------+
$tmp = User::findFirst('uid = 100');
$tmp->uid = 900;
$tmp->rate = 15;
$result = $tmp->save();
these codes cannot modify anything in the table , but it return the $result is true, is it a bug?
I think it should offer a method to modify primary key.
I don't think it is a bug, I suspect that the Phalcon developers would subscribe to the principle of having primary keys as immutable or set in stone. See questions like : Can we update primary key values of a table? and https://softwareengineering.stackexchange.com/questions/8187/should-a-primary-key-be-immutable/
If anything the bug could be that Phalcon allows you to change the primary key in the first place.
Knowing why you would want to change the primary key might help, because I can't think of any reason off the top of my head why you would want to do that. I believe the main (only?) purpose of the primary key is to identify that row in the table, and any joining tables, whether Robotina has a uid of 1, 11 or 111 shouldn't really matter as long as the entry is unique for all rows in the table.
If the purpose of change is some kind of ranking like a leader board, I would suggest adding a rank field, as it will likely be more efficient that changing a special primary key field.
If you absolutely have to change the uid, I would be inclined to create a new row and delete the old one, if that sounds messy bear in mind that depending on which database you are using that might be what the database engine is doing behind the scenes anyway, and also that the very concept of editing a primary key would set a lot of people's teeth on edge.

Can a foreign key refer to a primary key in the same table?

I just think that the answer is false because the foreign key doesn't have uniqueness property.
But some people said that it can be in case of self joining the table.
I am new to SQL. If its true please explain how and why?
Employee table
| e_id | e_name | e_sala | d_id |
|---- |------- |----- |--------|
| 1 | Tom | 50K | A |
| 2 | Billy | 15K | A |
| 3 | Bucky | 15K | B |
department table
| d_id | d_name |
|---- |------- |
| A | XXX |
| B | YYY |
Now, d_id is foreign key so how it can be a primary key. And explain something about join. What is its use?
I think the question is a bit confusing.
If you mean "can foreign key 'refer' to a primary key in the same table?", the answer is a firm yes as some replied. For example, in an employee table, a row for an employee may have a column for storing manager's employee number where the manager is also an employee and hence will have a row in the table like a row of any other employee.
If you mean "can column(or set of columns) be a primary key as well as a foreign key in the same table?", the answer, in my view, is a no; it seems meaningless. However, the following definition succeeds in SQL Server!
create table t1(c1 int not null primary key foreign key references t1(c1))
But I think it is meaningless to have such a constraint unless somebody comes up with a practical example.
AmanS, in your example d_id in no circumstance can be a primary key in Employee table. A table can have only one primary key. I hope this clears your doubt. d_id is/can be a primary key only in department table.
This may be a good explanation example
CREATE TABLE employees (
id INTEGER NOT NULL PRIMARY KEY,
managerId INTEGER REFERENCES employees(id),
name VARCHAR(30) NOT NULL
);
INSERT INTO employees(id, managerId, name) VALUES(1, NULL, 'John');
INSERT INTO employees(id, managerId, name) VALUES(2, 1, 'Mike');
-- Explanation:
-- In this example.
-- John is Mike's manager. Mike does not manage anyone.
-- Mike is the only employee who does not manage anyone.
Sure, why not? Let's say you have a Person table, with id, name, age, and parent_id, where parent_id is a foreign key to the same table. You wouldn't need to normalize the Person table to Parent and Child tables, that would be overkill.
Person
| id | name | age | parent_id |
|----|-------|-----|-----------|
| 1 | Tom | 50 | null |
| 2 | Billy | 15 | 1 |
Something like this.
I suppose to maintain consistency, there would need to be at least 1 null value for parent_id, though. The one "alpha male" row.
EDIT: As the comments show, Sam found a good reason not to do this. It seems that in MySQL when you attempt to make edits to the primary key, even if you specify CASCADE ON UPDATE it won’t propagate the edit properly. Although primary keys are (usually) off-limits to editing in production, it is nevertheless a limitation not to be ignored. Thus I change my answer to:- you should probably avoid this practice unless you have pretty tight control over the production system (and can guarantee no one will implement a control that edits the PKs). I haven't tested it outside of MySQL.
Eg: n sub-category level for categories .Below table primary-key id is referred by foreign-key sub_category_id
A good example of using ids of other rows in the same table as foreign keys is nested lists.
Deleting a row that has children (i.e., rows, which refer to parent's id), which also have children (i.e., referencing ids of children) will delete a cascade of rows.
This will save a lot of pain (and a lot of code of what to do with orphans - i.e., rows, that refer to non-existing ids).
Other answers have given clear enough examples of a record referencing another record in the same table.
There are even valid use cases for a record referencing itself in the same table. For example, a point of sale system accepting many tenders may need to know which tender to use for change when the payment is not the exact value of the sale. For many tenders that's the same tender, for others that's domestic cash, for yet other tenders, no form of change is allowed.
All this can be pretty elegantly represented with a single tender attribute which is a foreign key referencing the primary key of the same table, and whose values sometimes match the respective primary key of same record. In this example, the absence of value (also known as NULL value) might be needed to represent an unrelated meaning: this tender can only be used at its full value.
Popular relational database management systems support this use case smoothly.
Take-aways:
When inserting a record, the foreign key reference is verified to be present after the insert, rather than before the insert.
When inserting multiple records with a single statement, the order in which the records are inserted matters. The constraints are checked for each record separately.
Certain other data patterns, such as those involving circular dependences on record level going through two or more tables, cannot be purely inserted at all, or at least not with all the foreign keys enabled, and they have to be established using a combination of inserts and updates (if they are truly necessary).
Adding to the answer by #mysagar the way to do the same in MySQL is demonstrated below -
CREATE TABLE t1 (
-> c1 INT NOT NULL,
-> PRIMARY KEY (c1),
-> CONSTRAINT fk FOREIGN KEY (c1)
-> REFERENCES t1 (c1)
-> ON UPDATE RESTRICT
-> ON DELETE RESTRICT
-> );
would give error -
ERROR 1822 (HY000): Failed to add the foreign key constraint. Missing index for constraint 'fk' in the referenced table 't1'
The correct way to do it is -
CREATE TABLE t1 (
-> c1 INT NOT NULL,
-> PRIMARY KEY (c1),
-> KEY i (c1),
-> CONSTRAINT fk FOREIGN KEY (c1)
-> REFERENCES t1 (c1)
-> ON UPDATE RESTRICT
-> ON DELETE RESTRICT
-> );
One practical utility I can think of is a quick-fix to ensure that after a value is entered in the PRIMARY KEY column, it can neither be updated, nor deleted.
For example, over here let's populate table t1 -
INSERT INTO t1 (c1) VALUES
-> (1),
-> (2),
-> (3),
-> (4),
-> (5);
SELECT * FROM t1;
+----+
| c1 |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
Now, let's try updating row1 -
UPDATE t1
-> SET c1 = 6 WHERE c1 = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`constraints`.`t1`, CONSTRAINT `fk` FOREIGN KEY (`c1`) REFERENCES `t1` (`c1`) ON DELETE RESTRICT ON UPDATE RESTRICT)
Now, let's try deleting row1 -
DELETE FROM t1
-> WHERE c1 = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`constraints`.`t1`, CONSTRAINT `fk` FOREIGN KEY (`c1`) REFERENCES `t1` (`c1`) ON DELETE RESTRICT ON UPDATE RESTRICT)

Foreign keys in composite key

Suppose I have a table, Document, that looks something like this:
_______________________
| Document |
|-----------------------|
| DocumentId int PK |
| (add't fields) |
|_______________________|
Now suppose I have a second table:
_______________________
| DocumentVersion |
|-----------------------|
| DocumentId int PK, FK |
| VersionId int PK |
| (add't fields) |
|_______________________|
Finally, suppose I wish to create a third table that references DocumentVersion, perhaps an audit of users that have accessed each version (assume a User table exists):
_______________________
| VersionAccessLog |
|-----------------------|
| DocumentId int PK, FK |
| VersionId int PK, FK |
| UserId int PK, FK |
| AccessTime DateTime PK|
|_______________________|
Maybe not the best example but hopefully enough to illustrate my question.
Focusing on VersionAccessLog, we have:
PK(DocumentId, VersionId, UserId, AccessTime)
FK(DocumentId, VersionId) REFERENCES DocumentVersion
FK(userId) REFERENCES User
Now my question is, should I also in VersionAccessLog create a FK(DocumentId)? At first glance, the key seems superfluous-- referential integrity is enforced by the FK to DocumentVersion. However, from a relational algebra standpoint, should this key exist or not? From a practical standpoint (assume SQL Server 2012 if necessary), are there any performance implications of including or excluding the key?
There are performance impacts to including the additional key, because the database will check the FK on every insert (child) or delete(parent). From a practical perspective, I generally do not include the extra keys because there really isn't any value in the validations and there is the slight performance cost.
I would make sure that if the schema was ever changed and the FK between DocumentVersion and VersionAccessLog was removed, to add the FK between VersionAccessLog and Document. The only other time I could see adding it is if some Schema aware DAO library was used that reverses Has-a relationships from FK's, and it was worthwhile to include that.