Insert into 2 separate tables which are linked by primary key-foreign key - oracle-adf

Say I have 2 Table, Employee and Address with primary keys EmployeeID and AddressID respectively.
both tables are linked by the Address ID field and have one to one relationship.
Now in UI when I want to add a new Employee I want a single form where user can enter both the details from employee and address.
Both table have got the primary keys set as dbsequence in the EO and VO layer. There is a sequence and trigger implemented in the DB Layer.
The address should be inserted first and the addressID generated should reflect on the row inserted on the employee table.
How do I go about doing this?

Try to avoid setting values on the Database level since it causes the below error
another users changed the row with primary key...
Try to initialize the AddressId Column value on entity level (Address Entity Object) using the below expression
(new oracle.jbo.server.SequenceImpl("ADDRESS_ID_SEQ_NAME",adf.object.getDBTransaction())).getSequenceNumber()
Then you can create a ViewLink with 1 to 1 relation between Address And Employee So the AddressId Will be defaulted with same value for both Address And Employee

Related

Remove foreign key and reference tables in SQL Server

I have four tables Store, Employee, Customer, Address. I have linked the first three tables to Address. Now I want to remove this FK and reference these tables to the Address. How can I do it?
Table structure:
Store:
StoreID(PK), BranchName
Employee:
EmpID(PK), Name
Customer:
CustID(PK), Name
Address:
AddID(PK),
ID(FK to Store.StoreID, Employee.EmpID, Customer.CustID),
AddressDetail
I want to remove FK on Address.ID and just reference it to three tables.
You can remove a FOREIGN KEY constraint with an ALTER TABLE statement. For example
ALTER TABLE [Address] DROP CONSTRAINT [FK_Address_Store]
To remove a column, again, an ALTER TABLE statement.
ALTER TABLE [Address] DROP COLUMN [ID]
The data model you are trying implement is not at all clear. How many Address can be related to a Customer? Only one, or more than one? Can the same Address be associated with a Customer and an Employee? Can a specific Address be related to more than one Customer?
In my Entity Relationship models, "Address" is typically a composite attribute, and not an entity. Often, Address is a multi-valued attribute (e.g. a Customer can have more than one Address, or more than one PhoneNumber). Sometimes, an Addresses will be a particular type of Address (Shipping address, Billing address, Office address, Home address), just like phone numbers can be of a type (main, mobile, office, fax, etc.)
Without an understanding the data model, it's not possible to give you a recommendation on the changes you should make to your database tables to implement the model.

Relation between Inserted and Deleted table's in a trigger

Let's say I have this table :
Car
----------------------
Name|Date|Color
The primary key is a combination of Name and Date.
On the update, if the initial Color of the updated row is Blue and the new one is Red, I want to keep a trace of this update.
This is what I did :
ALTER TRIGGER TraceTrigger
ON Car
FOR UPDATE
AS
BEGIN
INSERT INTO TraceTable
SELECT
del.Name,
del.Date,
del.Color,
ins.Name,
ins.Date,
ins.Color
FROM deleted as del
INNER JOIN inserted as ins
ON del.Name = ins.Name AND del.Date = ins.Date
WHERE del.color = 'Blue' AND ins.Color = 'Red'
END
This example is pretty simple. It show that I need to keep a trace of X old value and X new value from the updated row.
But imagine if the Name can be modified (I know we should not modify PK, but in this situation, it is possible). Given that the primary key can change, sometimes, the relation between the INSERTED and DELETED table's will just not work.
So, it is possible to keep the relation between the deleted row and the inserted row when the PK can be updated to a different value ?
You needn't bother recording both INSERTED and DELETED. Just INSERTED is what I usually do, otherwise you'd end up with 2 of every bit of information. You'll record it when its inserted, then you'll record the identical data when its deleted.
Say you've got a table that just has an ID and a Name field, the trace for that recording both INSERTED and DELETED would look like:
OldID OldName NewID NewName
1 Harry 1 Henry
1 Henry 1 James
1 James 1 Thomas
As you can see, you're doubling up data. The left 2 columns are identical to the right columns except shifted up a row.
In terms of the primary key, if you know you might have to change the PK whilst wanting to maintain a history, I'd strongly recommend adding a surrogate key to the table (e.g ID) that you NEVER change, that way you are free to alter the name column as you wish.
You never really change a primary key; logically, you actually create a new entity (record / row ). It is, in effect, a completely new thing.
There are a number of ways to keep track of this change, but here are two:
Create a row identifier like an IDENTITY column. It's not really a surrogate key, because a surrogate key should always be 1-1 with the proper natural key. Use this if name + date is not really the primary key and you can't create one (yuck - you have a database design issue).
Update the data in your trace table to match the new value anytime a value in the PK changes. This is the proper solution if your database design is correct. You may be able to implement this with an ON UPDATE CASCADE foreign key constraint.

Change ID of row and reflect this change to all related tables

Old version
I have a Person table and the table Company.
both tables have a column Id (Identity)
Table Company have Ids of 1 to 165
In the table Person have Ids 1 until 2029
New Version
In the new version of the system, was created a table Entity.
This table contains the records of the Companies and People
The Company and Person tables will be maintained, referring to the Entity table.
The Id in table Entity will be the same in Company or Person table
Question
Both tables have multiple relationships with other tables.
Table Entity (as well as others) has a column ID (identity).
The problem is that the Id were repeated when the two tables together (It was to be expected).
How to import without losing relationships?
Attempts
I thought of changing the value of Ids in Company table, starts from 2030.
Thus the Ids would not duplicate when joining the two tables.
But this creates another questions.
How to do this without losing existing relationships?
How to change the Id of a row in the table and this is reflected in all tables which it relates?
I would like to do this using only DDL (SQL Server)
I thought of changing the value of Ids in Company table, starts from 2030. Thus the Ids would not duplicate when joining the two tables.
Create foreign key constraints on the Person table to all related tables (or alter the existing foreign key constraints) with ON UPDATE CASCADE. Then update the Person table and change the values if the id columns - these changes will cascade to the related tables.
To stop further problems, maybe change the identity columns in Person and Company to something like identity( 1000, 3 ) and identity (1001, 3) respectively.
However, I think the best idea is to have a different EntityID column in the Entity table, unrelated to PersonID and CompanyID. The Entity table would also have a column called AltEntityID or BusinessKey that contains the id from the other table and that does not have a unique constraint or a foreign key constraint.
And if you make small modification to your attempt - add new column, say newId, to Company and to Person to manage relation with Entity and leave id columns as is. Why this is the simpliest way? Because new columns shouldnot be identity columns, from one side. From the other side, you can leave all logic of relating other tables with Company and Person intact.

Inserting values into SQL Server database

I have created a web form with the following values
first name
last name
address line 1
address line 2
city
state
contact1
contact2
email id
password
confirm password...
Upon clicking the submit button, a stored procedure savedata is invoked.
The fields name, address and contacts are saved into table personal_details, while email and password are stored into login_detail.
The table personal_details has columns user_id int identity(1,1) pk...
Same user_id int identity(1,1) fk is defined in login_detail table...
Now, is it possible that 2 users 1 and 2 submit the form at the same time and user1's personal details get pushed in table and then user2's personal details get pushed.
Generating id as 1 and 2 respectively...
but for login details user2 data get pushed first then user1...generating ids 1 and 2... which are wrong....
Is there any other method to get the same ids for both the tables?
thanks
And this is my first question...sorry if I am not able to frame it properly...
You should perform the following sequence of steps in a single transaction to ensure the atomicity of this save operation:
BEGIN TRANSACTION
Insert record into the personal_details table.
Obtain the user_id corresponding to this new record added.
Insert record into the login_details table with the user_id as the one obtained in the previous step.
COMMIT TRANSACTION.
Also, it doesn't seem appropriate to "vertically partition" the details of a user across two tables when there is a one-to-one correspondence between records in these two tables. You could just have a single table unless there are attributes of a user that carry multiple values for a single user id i.e. one-to-many relationship.

How to create 1 to 1(or zero) relationship in SQL Server 2008

I know how to create one to one relationship only problem is that it demands rows in both tables e.g. i have a table
emp_table => key1, key2, name, description
emp_address_table => key1, key2, address
system do not put mandatory constraints on address so an emp may exist without having his/her address, OR emp may have maximum one address not more that that so it seems
1:1(0) relationship
please let me know how can i do that in sql server 2008
You can't have a constraint that enforces the existence of a child row because you can't insert the two rows at the same time. I.e. whether you insert your employee, or employee address row first, you would have an invalid constraint at this point.
So all constraints in SQL are '0 or more' and never '1 or more' or 'exactly 1'.
You can enforce a '0 or 1' constraint by adding a UNIQUE constraint to the foreign key column in the emp_address table. This will ensure there can be at most one emp_address row that refers to a given employee.
Use an association table. It's better practice anyway and you can use it too implement 0 to N relationships easily, where:
Absence of rows in the association table represents 0:0
Presence of a single row in the association table per entity represents 1 to 1
Presence of multiples rows in the association table (per entity) represents 1 to many
*emp_table*
key1
key2
name
description
*address_table*
addr_key
address
*emp_address_table*
key1
key2
addr_key
In your association table, make key1 and key2 a foreign key reference back to your employee table, and addr_key a foreign key reference back to the address table. If you want to enforce a 1 to 1 relationship, make key1, key2 a unique constraint on the association table. Otherwise, leave the unique constraint to represent 0 to many relationship.
Try
SELECT *
FROM emp_table et
LEFT OUTER JOIN emp_address_table edt ON et.key1 = edt.key1 AND et.key2 = edt.key2
You can not enforce having row in child table by using constraints. (because you first insert row in parent table and only then in child table- its not one operation but 2, even though it most possibly one transaction)
But you can use stored procedure to insert data and you can do validation inside a procedure.

Resources