How to get primary key of a system table in oracle? - database

I know one can query what is the primary key of a user table in Oracle database. But how can I do this for a system table, for example to know what is the primary key of all_objects table?

There is not difference between "user tables" and "system tables" - their primary keys can all be queried from the data dictionary in the same fashion.
all_objects, however, is not a table - its a view. Therefore, it doesn't have a primary key, so you cannot query it.

Figure out what the actual table is first.
Do an explain plan on SELECT * FROM ALL_TABLES;
You'll see a scan of SYS.OBJ$ - that's the table you're looking for.
A query of constraints of type 'P' from ALL_CONSTRAINTS doesn't show any entries for that table, so no primary key on that table.
I don't think this is your real question though. What are you really looking to get at?
By the way, views can actually have constraints defined on them, that's been a feature since 10g I believe.

Related

Isolated table and foreign key constraint

I have got two questions when designing a database for a sales system.
Is it possible to have a isolated table, which means a table does not have relationship with all other tables?
How to solve the following issue:
Table: SalesOrderDetail, Table: InventoryTrans
Every record in SalesOrderDetail will insert into InventoryTrans, but not all records in InventoryTrans are from SalesOrderDetail. Because other tables may also insert records into the InventoryTrans.
Therefore, I want to add a reference column SalesOrderDetailID to InventoryTrans table, but does not specify FK constraint. Because if the record is not from SalesOrderDetail table, then the SalesOrderDetailID should be null.
Is this the right design?
Yes, you can have a table that has no foreign key references to other tables. A table that stores various configuration settings is probably the most common, but there are others.
The column InventoryTrans.SalesOrderDetailID can be a nullable foreign key reference. But you haven't provided enough detail to tell whether that's a good design decision. Making an educated guess, I'd say probably not. (Other kinds of transactions would probably benefit from a foreign key reference.)

Can't work around this foreign key constraint rule using TRIGGER in SQLite?

First, I want to talk a little about the Foreign key constraint rule and how helpful it is. Suppose I have two tables, a primary table with the primary column called ID, the other table is the foreign one which also has a primary column called ID. This column in the foreign table refers to the ID column in the primary table. If we don't establish any Foreign key relation/constraint between those tables, we may fall foul of many problems related to integrity.
If we create the foreign key relation for them, any changes to the ID column in primary table will 'auto' reflect to the ID column in the foreign table, changes here can be made by DELETE, UPDATE queries. Moreover, any changes to the ID in the foreign table should be constrained by the ID column in the primary table, for example there shouldn't any new value inserted or updated in the ID column of the foreign table unless it does exist in the ID column of the primary table.
I know that SQLite doesn't support foreign key constraint (with full functions as detailed above) and I have to use TRIGGER to work around this problem. I have used TRIGGER to work around successfully in one way (Any changes to the ID column in the primary table will refect to the ID column in the foreign table) but the reverse way (should throw/raise any error if there is a confict occurs, for example, there are only values 1,2,3 in the ID column of the primary table, but the value 2 in the ID column of the foreign table is updated to 4 -> not exist in the primary table -> should throw error) is not easy. The difficult is SQLite doesn't also support IF statement and RAISERROR function. If these features were supported, I could work around easily.
I wonder how you can use SQLite if it doesn't support some important features? Even working around by using TRIGGER is not easy and I think it's impossible, except that you don't care about the reverse way. (In fact, the reverse way is not really necessary if you set up your SQL queries carefully, but who can make sure? Raising error is a mechanism reminding us to fix and correct and making it work exactly without corrupting data and the bugs can't be invisible.
If you still don't know what I want, I would like to have some last words, my purpose is to achieve the full functionality of the Foreign key constraint which is not supported in SQLite (even you can create such a relationship but it's fake, not real as you can benefit from it in SQL Server, SQL Server Ce, MS Access or MySQL).
Your help would be highly appreciated.
PS: I really like SQLite because it is file-based, easy to deploy, supports large file size (an advantage over SQL Server Ce) but some missing features have made me re-think many times, I'm afraid if going for it, my application may be unreliable and corrupt unpredictably.
To answer the question that you have skillfully hidden in your rant:
SQLite allows the RAISE function inside triggers; because of the lack of control flow statements, this must be used with a SELECT:
CREATE TRIGGER check_that_id_exists_in_parent
BEFORE UPDATE OF id ON child_table
FOR EACH ROW
BEGIN
SELECT RAISE(ABORT, 'parent ID does not exist')
WHERE NOT EXISTS (SELECT 1
FROM parent_table
WHERE id = NEW.id);
END;

ForeignKey and fetching performance

Let's consider the following scenario: I've a "master table" with a "detail" table. The detail table have just a foreign key pointing to the primary one ( not a primary key ). This is the schema that NHibernate generates for me when I map a simple bag. My question is, does the FK itself on the detail table suffices to have queryes without full scan? In other world, having or not having the FK defined on the detail table, does change the performance? I guess yes, but I don't know if I'm right, or where to find a source to explain it.
In both cases (FK or no FK) you'll have to create an index on the FK field in the details table to prevent a table scan. In sql server, when creating an FK constraint an index is not created automatically.
See MSDN, "Indexing FOREIGN KEY Constraints".

Creating relationships between tables

My question specifically about sql-server, but probably can be answered by anyone with any database background
If I want table A to have a 1:1 relationship with table B on a certain column, should I somehow modify the CREATE TABLE statement to identify this relationship or is this something that is not done at all (and rather it is handled by logic)?
EDIT
The second part of my question is: what is the point of embedding this into the code? why not just handle it logically on selects/updates?
All you need to do is have the column in Table A be a foreign key to the primary key of Table B:
create table TableB (
Id int primary key identity(1,1),
Name varchar(255))
create table TableA (
Id int primary key identity(1,1),
Name varchar(255),
TableBRelation int unique,
foreign key (TableBRelation) references TableB (Id))
The SQL may not be perfect but you should be able to get the idea.
As for why you would want to do this in the database rather than just application logic:
Other databases or developers may try to access your database. Do you want them to be able to create invalid data that may break your application? No. That's one of the points of referential integrity.
At some point, somebody is going to have to maintain your application. Defining your keys at the database level will clearly identify relationships between your data rather than requiring the develop to dig through your application code.
To create a 1:1 relationship just make the B table column a foreign key or unique. This will ensure that there can be only one column in table B that matches the PK field in table A and that way you effectively get a 1:1 relationship...
You can setup a foreign key and add a constraint for it to be unique. This would setup a 1:1 relationship between your tables.

changing the primary key value in SQL server 2005

I have a Table which has a Primary Key field which is not set to auto-increment.
I want to change one of these primary keys to something different.
The problem arises with the other tables relations. The thing is, the guy who built this system did not build relations in SQL Server, but rather manually coded some override in the program that uses it - a VB 6 program.
How would I update a Primary Key and all instances of the Primary Key in other databases? I have to manually look for the instances(although I do know they are in only two tables) of the Primary Key and change them, but how do I do that?
Even though the person who first created the tables didn't include foreign keys to them, you can add them now if foreign keys are honored in your tables. When you create the foreign keys, create them with ON UPDATE CASCADE option. This way, when you update your primary key, the related foreign keys will also be updated.
One thing I would suggest is using the query of:
select * from INFORMATION_SCHEMA.Columns where Column_Name = 'FieldID'
This queries the metadata to see all where that field exists, just in case there are more. Then, just write an update script to change the key, unfortunately its a manual process but being that the relationship is missing it will make scripting easier.

Resources