I am creating a database table and want to make sure that data in one of the column is always bounded by data in a column of another table. for example:
Table_1 has Column_1
Column_1 can have values:
v1
v2
v3
v4
v2
v3
Now I am trying to create Table_2 with Column_3
and want to make sure that values in this column is always a subset of Table_1:Column_1
Is there a constraint I can apply to achieve this?
In Oracle and PostgreSQL, use a check constraint
eg, in Oracle:
ALTER TABLE Table_3
ADD CONSTRAINT my_name
CHECK
(column_3 in
(SELECT Column_1 FROM Table_1))
This also works with PostgreSQL
In SQL Server and DB2, I believe, you have to create a function that does the actual test, but otherwise it's the same. The function would have a single argument (column_3's value) and return EXISTS (SELECT 1 FROM Table_1 WHERE Column_1 = argument).
Unfortunately, in MySQL you will need to use on insert and update triggers
Is Table_1.Column_1 unique?
If yes, just make it a PRIMARY KEY or UNIQUE, then reference it from FOREIGN KEY on the Table_2.Column_3.
If no (as apparently implied by your example), make a FK from Table_2 to Table_1's primary key. The Table_2.Column_3 won't even exist, instead you'll get the values of Table_1.Column_1 by JOIN-ing the two tables. You can put that JOIN in a VIEW to make it appear (to the client applications) as if the Table_2.Column_3 actually exists.
Related
When I add news rows using the Insert into select code, the new rows get added randomly in between the already existing rows, instead of getting added to the end of the table.
I'm using, Insert into Table1 (Name1) select Name from Table2.
SQL tables are modeled after unordered sets, and hence you should not assume that there is any order to your data in the table. The only order which exists is what you specify when you query using ORDER BY, e.g.
SELECT Name1
FROM Table1
ORDER BY Name1
An index can also be thought of a way of ordering your records, but these two are mostly distinct entities from your actual table.
I agree with Tim's answer. But if you still want the data inserted in the way you want, then you can try to add the primary key yourself which is incremental (like 1,2,3 ... or 10,20,30 ...).
Although I don't recommend it, but I think following can help you if you don't want to handle the primary key yourself.
How do I add a auto_increment primary key in SQL Server database?
As you know, we can use 'select into table' to copy table structure in sql server, but there's a problem when the column of source table has default value, the default value setting is missing in the newly created table.
So, how can I keep the default value setting? any clue? thanks.
I hate to break it to you, but that's NOT the only thing missing. I assume by "the default value setting" you actually mean default constraints, i.e. Specify Default Values for Columns or Defaults.
The table is created using the most basic structure and does not copy (at least the following)
clustered index
any other index for that matter
referential constraints
any other constraints for that matter
It makes more sense when you consider this scenario
select a.clustered_id a_id, b.clustered_id b_id, b.name
from tablea a
join tableb b on ....
Should it create a clustered index on a_id or b_id (which may not even be unique after this JOIN)!? Granted you're thinking of the scenario of a single table (direct clone), but that really is a very specific use case for a generic functionality.
I have a table, Contacts, with a primary key of ContactID, which is an identity column. I have another table, Person, with a primary key of PersonID that is a foreign key to ContactID. When I insert a record into Person, I would like PersonID to pull the corresponding identity from ContactID in Contact.
In Access, I simply make a query that references both tables, and it will fill in the foreign key column with the corresponding value in the identity (autonumber) column.
SELECT Person.PersonID, Person.FirstName, Person.MiddleName, Person.LastName, Contact.ContactID, Contact.EmailAddress, Contact.PhoneNumber
FROM (Contact INNER JOIN Person ON Contact.ContactID = Person.PersonID);
How can we achieve this in SQLServer 2008 R2? I have been programming triggers to update the keys, but it seems like there ought to be a better way.
Thank you very much for your assistance.
When you insert to the first table, you use the OUTPUT clause to pull the identity value and then you can use it to insert to the child table.
You can also use scope_identity() to do the same thing, but OUTPUT is the preferred method. Do not under any circumstances use ##Identity as it often will give incorrect results and mess up your data integrity.
Look up how to use them in Books Online.
If I have a table with an identity column as the primary key, I would use scope_identity() to retrieve latest identity value inserted during scope. What if the primary key is not an identity column, but an nvarchar(256) with a default value of newid() to generate the value. After performing the insert, is there a function that I can use to retrieve that value and store it in some variable? I'll need to insert this value into other column ID's in other tables.
Here's an example of what I'm referring to. In the aspnet_Users table the userID is described like above, if I wanted to use the userID as a FK in my own table, would it be ok to use that autogenerated newid() value or is there a better way? If this is the best way how do I store it easily?
Thank you
The OUTPUT clause of the INSERT is what you are looking for. See this MSDN article.
basically:
DECLARE #newkey TABLE (keys varchar(25));
INSERT INTO actual_table (nonAutoIncId,other1,other2,other3)
OUTPUT INSERTED.nonAutoIncId INTO #newkey
VALUES ('NewId',1,2,3)
I am using Sql Server with Composite key. In this composite key contains one identity column i.e Auto incrment value. i want to generate in this column with duplicate values. How can i do this. Please give me a solution for this.
Thanks with Regards
Saravanan.M
The identity column cannot(corrected based on feedback from #AlexKuznetsov) should not have duplicates within the column itself - it is generally meant to be a unique column and a provide non-identifying value for each row.
If you are asking how to put values into the identity column that already exist in another column, you have to do the following:
Set IDENTITY_INSERT Schema.TableName ON
Insert Into TableName (PK1, PK2, IdentityCol1, OtherCol1, OtherCol2)
SELECT FirstCol, SecondCol, SecondCol, OtherColumn1, OtherColumn2
FROM SomeOtherTable
Set IDENTITY_INSERT Schema.TableName OFF
note that PK2 and IdentityCol1 both get the same value
It would be good if you could provide more context around what you are wanting to do and why? There are some good reasons to use composite keys, but if you're already using an identity field, why not make that your primary key?
Your auto-incrementing identity column should be left untouched and should continue to uniquely identify your rows. It is generally good practice to always have an abstract identity column as your primary key.
If you have 2 other values in your data model which uniquely identify your row, they should be in 2 other columns. If one of them is an auto-incrementing number then you can generate the value either in a stored proc which is used for all insertions or in an insert trigger.
Although this is not quite an answer, several answerers have made one and the same mistake, claiming that "You cant have an identity column with duplicates". In fact, identities may easily be not unique if you do not enforce their uniqueness by an index or constraint, as follows:
CREATE TABLE identityTest(i INT IDENTITY(1,1));
GO
INSERT identityTest DEFAULT VALUES;
INSERT identityTest DEFAULT VALUES;
SET IDENTITY_INSERT identityTest ON;
INSERT INTO identityTest(i)
SELECT i FROM identityTest;
SET IDENTITY_INSERT identityTest OFF;
SELECT i FROM identityTest;
i
-----------
1
2
1
2
GO
DROP TABLE identityTest;