SQL Express 2008 - table 2 column1 equals table1 column1 - sql-server-2008-express

I have two tables:
table1 has staffid
table2 has staffid
I want table2 staffid to be equal to table1 staffid
and when changes are made to table 1 staff id they need to change staffid in table2
How do I do this?

CREATE TRIGGER [dbo].[TestDb] ON [dbo].[Table1]
AFTER UPDATE
AS
BEGIN
DECLARE #staffID int
SELECT staffID = staffID FROM INSERTED
-- do something for update in table 2
END
You can use BEFORE UPDATE or AFTER UPDATE trigger to achieve your task
Here is the reference http://msdn.microsoft.com/en-us/library/ms189799.aspx

As your first requirement is table2 staffid should be to equal table1 staffid, you can define a foreign key constraint on table2 staff id as:
ALTER TABLE table2 WITH NOCHECK
ADD CONSTRAINT FK_staffid
FOREIGN KEY(staffid)
REFERENCES table1(staffid)
ON UPDATE CASCADE
Foreign key option ‘With check’ specifies that any existing data in the foreign key table [ie Table2 ] should be validated to conform to the constraint whereas ‘WITH NOCHECK’ setting specifies that existing data is not validated to conform to the new constraint.This option can make the creation process more efficient when you know that all existing data in Table2 already conforms to the constraint, but any non-conforming records will be ignored during the creation. However, during subsequent updates to the non-conforming row, the constraint will be enforced, resulting in an error.
Also second requirement is changes made to table1 staffid should be cascaded to staffid in table2 ‘ON UPDATE CASCADE’ option should be used.

If you want it to be done automatically, you need to use ON UPDATE CASCADE for the table2 staffid.

Related

How do I switch two ID [PK] on postgres database?

I want to change the ID on two rows on Postgres, to switch them. They are already defined as foreign key so I cannot use a third number to do the switch.
How can I do this in one SQL query or transaction?
Example:
UPDATE mytable SET id=2 WHERE ID=1;
UPDATE mytable SET id=1 WHERE ID=2
You mention foreign keys, but it remains unclear whether id is the referenced or the referencing column of a foreign key constraint.
If id is the referenced column you just define the fk constraint ON UPDATE CASCADE. Then you can change your id as much as you want. Changes are cascaded to the depending columns.
If id is the referencing column (and no other foreign key constraints point to it), then there is another, faster way since PostgreSQL 9.0. You can use a deferrable primary or unique key. Consider the following demo:
Note that you can't use this if you want to reference id with a foreign key constraint from another table. I quote the manual here:
The referenced columns must be the columns of a non-deferrable unique
or primary key constraint in the referenced table.
Testbed:
CREATE TEMP TABLE t
( id integer
,txt text
,CONSTRAINT t_pkey PRIMARY KEY (id) DEFERRABLE INITIALLY DEFERRED
);
INSERT INTO t VALUES
(1, 'one')
,(2, 'two');
Update:
UPDATE t
SET id = t_old.id
FROM t t_old
WHERE (t.id, t_old.id) IN ((1,2), (2,1));
Result:
SELECT * FROM t;
id | txt
---+-----
2 | one
1 | two
You can also declare the constraint DEFERRABLE INITIALLY IMMEDIATE and use SET CONSTRAINTS ... DEFERRED in the same transaction.
Be sure to read about the details in the manual:
CREATE TABLE
SET CONSTRAINTS
Even seems to work with DEFERRABLE INITIALLY IMMEDIATE and no SET CONSTRAINTS. I posted a question about that.
begin;
alter table mytable drop constraint_name;
UPDATE mytable SET id=-1 WHERE ID=1;
UPDATE mytable SET id=1 WHERE ID=2;
UPDATE mytable SET id=2 WHERE ID=-1;
alter table mytable add table_constraint;
commit;
Have you tried something like:
BEGIN;
CREATE TEMP TABLE updates ON COMMIT DROP AS
SELECT column1::int oldid, column2::int newid
FROM ( VALUES (1, 2), (2, 1) ) foo;
UPDATE mytable
FROM updates
SET id = newid
WHERE id = oldid;
--COMMIT;
ROLLBACK;
Of course rollback gets commented out and commit in when you are ready to go.

Replace Create Trigger with Foreign Key (RI)

Create Trigger:
SELECT #oldVersionId = (SELECT DISTINCT VERSION_ID FROM Deleted)
SELECT #newVersionId = (SELECT DISTINCT VERSION_ID FROM Inserted)
SELECT #appId = (SELECT DISTINCT APP_ID FROM Deleted)
UPDATE [TableName]
SET [VERSION_ID] = #newVersionId
WHERE (([VERSION_ID] = #oldVersionId) AND ([APP_ID] = #appId) )
Can this Trigger be replace with a Foreign Key to update the VERSION_ID ?
What I think could be a problem is the AND condition, how to express that in a FK with On del/update Cascade?
FOREIGN KEY CONSTRAINTS don't update anything. They check the values being written to a record and cause the write to fail if they cause a constraint to fail.
Also, as #marc_s points out in his comment, triggers in MS SQL Server are set based. The INSERTED and DELETED tables can hold multiple records at once. Your code only works for one record.
You could try something along these lines...
UPDATE
table
SET
VERSION_ID = inserted.VERSION_ID
FROM
table
INNER JOIN
deleted
ON table.VERSION_ID = deleted.VERSION_ID
AND table.APP_ID = deleted.APP_ID
INNER JOIN
inserted
ON deleted.PRIMARY_KEY = inserted.PRIMARY_KEY
EDIT
I just read your comment, and I think I understand. You want a foreign key constraint with ON UPDATE CASCADE.
You use this format to create that with DDL.
ALTER TABLE DBO.<child table>
ADD CONSTRAINT <foreign key name> FOREIGN KEY <child column>
REFERENCES DBO.<parent table>(<parent column>)
{ON [DELETE|UPDATE] CASCADE}
Or you could just SQL Server Management Studio to set it up. Just make sure the ON UPDATE CASCADE is present.
I cannot really tell you what you're looking for - you're too unclear in your question.
But basically, if two tables are linked via a foreign key constraint, of course you can add a clause to that to make sure the child table gets updated when the parents table's PK changes:
ALTER TABLE dbo.ChildTable
ADD CONSTRAINT FK_ChildTable_ParentTable
FOREIGN KEY(ChildTableColumn) REFERENCES dbo.ParentTable(PKColumn)
ON UPDATE CASCADE
The ON UPDATE CASCADE does exactly that - if the referenced column (the PKColumn in ParentTable) changes, then the FK constraint will "cascade" that update down into the child table and update it's ChildTableColumn to match the new PKColumn
Read all about cascading referential integrity constraints and what options you have on MSDN Books Online

SQL Server foreign key constraint - pair (same tuple)

Suppose these 2 tables:
tbl1
ID
name
fkID1
fkID2
tbl2
ID
pkID1
pkID2
Whenever data is inserted into tbl1, how can I ensure (fkID1, fkID2) exists as a row (tuple) in tbl2 in the form (pkID1, pkID2)?
I have no problem making a constraint so fkID1 must exist and that fkID2 must exist but I want to ensure they exist in the same row.
Either via SQL or instructions to create it via management studio would be great.
You can just comma delimit the columns you want to check. Just make sure they're in order.
alter table tbl1 with check
add constraint FK_tbl1_tbl2
foreign key (fkID1, fkID2)
references tbl2 (pkID1, pkID2)

How to cascade update 2 tables whose foreign key is not set to cascade?

I got 2 tables. They have a foreign key relation. But the foreign key is not set to update cascade. Now I want to update the table's primary key. SQL Server always prevent me from doing that because of the FK. How could I do it in SQL command? I don't have the right to modify the FK.
Thanks.
Why would you want to do this? It strikes me as potentially hazardous.
Your SQL would need to update the related table first NULLing the links back to the PK table and storing the IDs of the records effected. Then you can update the PK in the PK table. Then go back and update the FKs in the related tables.
Create new rows based on the existing row's attribute values but using the new key value. Do the same for all referencing tables. Then, using the new old key value, delete rows from the referencing tables then the referenced table. Something like:
INSERT INTO Table1 (key_col, attrib_col1)
SELECT 'new_key_value', attrib_col1
FROM Table1
WHERE key_col = 'old_key_value';
INSERT INTO Table2 (key_col, attrib_col2)
SELECT 'new_key_value', attrib_col2
FROM Table2
WHERE key_col = 'old_key_value';
DELETE
FROM Table2
WHERE key_col = 'old_key_value';
DELETE
FROM Table1
WHERE key_col = 'old_key_value';
You should only need to INSERT new rows for the parent table and UPDATE the child rows after the fact...
INSERT INTO ParentTable (PKColumn, attribute1, attribute2)
SELECT 'NewPKValue', attribute1, attribute2
FROM ParentTable
WHERE PKColumn = 'OldPKValue'
;
UPDATE ChildTable
SET FKColumn = 'NewPKValue'
WHERE FKColumn = 'OldPKValue'
;
DELETE
FROM ParentTable
WHERE PKColumn = 'OldPKValue'
;
Now for the gotchas:
1.) The above code wont work if there are any unique indexes defined on non-PK columns in the parent table and you need to use the current records' non-PK data values without modification.
2.) Since you're asking this question, I'm assuming your Parent table is not using an IDENTITY column as the PK.
3.) The code is certainly less than efficient. If your db has to do this infrequently on a few rows, you should be fine. If you need to do this 80 times per second, then I would strongly suggest you talk to the programmer/DBA or vendor, if they're at all available, about updating the FK definition to include ON UPDATE CASCADE.
4.) Make sure that there aren't any triggers on either table that would lead to unintended side effects when you create the new parent records or update the child records.

Sql Server 2008 check constraint

I have two tables, Table1 and Table2 with same primary key (FKTestID).
If I want to delete one row in Table1 and same FKTestID are in Table2 it will not work. You can only delete a row from Table1 if Table1.FKTestID not equals any FKTestID in Table2.
Please help me with this constraint?
You need to set the constraint to cascade on delete.
You can do this through SQL management studio by modifying the constraint.
Or you can do this via SQL when you created the constraint by including ON DELETE CASCADE at the end
You could also do it with the ALTER TABLE command.
Here is a code sample implementing what Simon suggested above.
CREATE TABLE dbo.Table1 (
FKTestID int NOT NULL PRIMARY KEY
)
GO
CREATE TABLE dbo.Table2 (
FKTestID int NOT NULL PRIMARY KEY
)
GO
ALTER TABLE dbo.Table2
ADD CONSTRAINT FK_Table2_FKTestID
FOREIGN KEY (FKTestID)
REFERENCES dbo.Table1 (FKTestID)
ON DELETE CASCADE
GO
INSERT INTO dbo.Table1 VALUES (1)
INSERT INTO dbo.Table2 VALUES (1)
INSERT INTO dbo.Table1 VALUES (2)
INSERT INTO dbo.Table2 VALUES (2)
DELETE FROM dbo.Table1 WHERE FKTestID = 1
SELECT 'Table1' AS [Table], * FROM dbo.Table1
SELECT 'Table2' AS [Table], * FROM dbo.Table2
=============================================
Table FKTestID
------ -----------
Table1 2
Table FKTestID
------ -----------
Table2 2
Note that I agree with Mitch Wheat's comment about CASCADE DELETE being dangerous. This feature is interesting, but I have never, ever used it in a production system.
If you are asking how to get rid of the constraint so that you can delete, DO NOT consider doing that. The constraint is there for a reason. If you don't know the reason, don't delete it.
Others have suggested adding a cascade delete. I suggest that this is poor idea as you can cause performance problems on the database. It is better to write a script that deletes the records in the correct order. In this case you need to delete the matching records from tables2 first, then run the delete on table 1.
You also need to evaluate the data in table2 before deciding to delete from it either by script or by cascade delte. If you should not be deleting those records from table2, then you should not be delting the records from table1 (by removing the constraint) as this will casue the table 2 records to be orphaned and you will lose the integrity of the data (which should be your first concern in any database actions (security and performance being a very close second and third)).
Let me give you a scenario where the data in table 2 would indicate you should not delete the record. Suppose you have a customer table and and order table. You want to delete customer A, but he has an order in the past. If you delete both records, you will mess up all the accounting information on orders. If you delete the customer but not the order (by eliminating the constraint), then you have an order that you can no longer tell who it was sent to. The correct thing to do in a case like this is to have an ISactive file in the customers table and mark him as an inactive customer. You would of course need to redesign the code that searches for customer information to make sure it includes the flag to only select active customers which is why this sort of thing should be thought out at the beginning of development not later (one reason why it is worth your while to hire database specialists for the design phase as many application developers don't consider maintaining the data over time as part of their design process).