Create a better designed database - where to put the foreign key - sql

Suppose I have 2 tables in my database and 2 Windows Forms (C#) for each table Section and Pages. Now each Section can have 10 Pages.
Note that I am creating a Windows Forms app and first form looks like this
FORM 1 (For Section Table)
And my second form for table pages looks like this:
FORM 2 for Pages Table.
By clicking on each Section, user will be directed to the 2nd form where user will/can have 10 pages.
I have this:
create table Section
(
Sectionid int primary key,
SectionName varchar,
Pageid int
)
create table Page
(
Pageid int primary key,
Pagetitle varchar,
Noteid int
)
foreign key(pageid) references Page(pageid)
I am confused how to insert data to the database once you have created a page.
AGAIN: 1 SECTION CAN HAVE AT LEAST 10 PAGES AND 1 PAGE CAN HAVE 1 NOTE.
If I have not made it easier to understand please just use Microsoft's One Note mobile app, I am basically copying it - thanks.

once you introduce constraints into the schema you need to be deliberate with how to insert data.
(temp tables don't enforce constraints like this)
CREATE TABLE #Pages (PageID INT IDENTITY PRIMARY KEY, PageTitle NVARCHAR(20), NoteID INT)
CREATE TABLE #Sections (SectionID INT IDENTITY PRIMARY KEY, SectionName NVARCHAR(20), PageID INT CONSTRAINT FK_PageID REFERENCES #Pages(PageID))
Now we have our tables, complete with constraints. The FK must exist in the referenced table.
DECLARE #KeyTable TABLE (PageID INT)
INSERT INTO #Pages (PageTitle, NoteID)
OUTPUT INSERTED.PageID INTO #KeyTable
VALUES ('Some Page', NULL)
INSERT INTO #Sections (SectionName, PageID)
SELECT 'Some Section', PageID
FROM #KeyTable
INSERT INTO #Sections (SectionName, PageID)
SELECT 'Another Section', PageID
FROM #KeyTable
When we insert a page we can capture the ID generated (or provided if it's not also an identity) and hold it in a table variable. We can then use it in the insert into Sections as well.
When you're actually doing this you may want to build some logic around checking if a page already exists and populating the table variable with the appropriate existing PageID if it does or doing the insert and propulating the PageID this way if it does not.

The relation between section an page is 1: n.
You can formulate it as:
One section has multiple pages, but one page only has one section. You always have to put the foreign key in the "n" table, which is in this case the "page".
So you have something like that, tell me your database and I can write you a exact sql:
Create Table Section(
Sectionid int primary key,
SectionName varchar,
)
Create Table Page(
Pageid int,
pagetitle int,
Noteid int,
PRIMARY KEY(PageId),
FOREIGN KEY (SectionId) References Section(SectionId)
)
...but I guess the pagetitle is also a varchar?
If you want to insert data, it is easy for the section. A simple insert statement. If you want insert data in the page object, you have to insert the id of the section for the column "SectionId".
Example:
Insert into table Section (Sectionid, SectionName) values (12,'test');
Insert into table Page (Pageid, Sectionid) values(1,12);
The value "12" you insert is the id of the section.

Related

Securing values for other tables from enumerable table in SQL Server database

English is not my native language, so I might have misused words Enumerator and Enumerable in this context. Please get a feel for what I'm trying to say and correct me if I'm wrong.
I'm looking into not having tables for each enumerator I need in my database.
I "don't want" to add tables for (examples:) service duration type, user type, currency type, etc. and add relations for each of them.
Instead of a table for each of them which values will probably not change a lot, and for which I'd have to create relationships with other tables, I'm looking into having just 2 tables called Enumerator (eg: user type, currency...) and Enumerable (eg: for user type -> manager, ceo, delivery guy... and for currency -> euro, dollar, pound...).
Though here's the kicker. If I implement it like that, I'm loosing the rigidity of the foreign key relationships -> I can't accidentally insert a row in users table that will have a user type of some currency or service duration type, or something else.
Is there another way to resolve the issue of having so many enumerators and enumerables with the benefit of having that rigidity of the foreign key and with the benefit of having all of them in just those 2 tables?
Best I can think of is to create a trigger for BEFORE UPDATE and BEFORE INSERT to check if (for example) the column type of user table is using the id of the enumerable table that belongs to the correct enumerator.
This is a short example in SQL
CREATE TABLE [dbo].[Enumerator]
(
[Id] INT NOT NULL PRIMARY KEY,
[Name] VARCHAR(50)
)
CREATE TABLE [dbo].[Enumerable]
(
[Id] INT NOT NULL PRIMARY KEY,
[EnumeratorId] INT NOT NULL FOREIGN KEY REFERENCES Enumerator(Id),
[Name] VARCHAR(50)
)
INSERT INTO Enumerator (Id, Name)
VALUES (1, 'UserType'),
(2, 'ServiceType');
INSERT INTO Enumerable (Id, EnumeratorId, Name) -- UserType
VALUES (1, 1, 'CEO'),
(2, 1, 'Manager'),
(3, 1, 'DeliveryGuy');
INSERT INTO Enumerable (Id, EnumeratorId, Name) -- ServiceDurationType
VALUES (4, 2, 'Daily'),
(5, 2, 'Weekly'),
(6, 2, 'Monthly');
CREATE TABLE [dbo].[User]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY (1,1),
[Type] INT NOT NULL FOREIGN KEY REFERENCES Enumerable(Id)
)
CREATE TABLE [dbo].[Service]
(
[Id] INT NOT NULL PRIMARY KEY IDENTITY (1,1),
[Type] INT NOT NULL FOREIGN KEY REFERENCES Enumerable(Id)
)
The questions are:
Is it viable to resolve enumerators and enumerables with 2 tables and with before update and before insert triggers, or is it more trouble than it's worth?
Is there a better way to resolve this other than using before update and before insert triggers?
Is there a better way to resolve enumerators and enumerables that is not using 2 tables and triggers, nor creating a table with relations for each of them?
I ask for your wisdom as I don't have one or more big projects behind me and I didn't get a chance to create a DB like this until now.

Design SQL tables

I have a set of business objects, which will need to store properties specific to the object type. I want these properties to be definable by the user at runtime. My solution for that is to have a table for each object type that contains the property keys for that object type.
For example, a user object may have a set of properties: fname, lname, address, phone, SSN. And if desired, that list can be built upon within the application, to now include email.
I then have a set of tables which contain all the possible values for a given property. So I'd have a table containing all addresses, a table containing all emails, etc. These may be used by different object types, and some property keys may have multiple values. If a a new property is created, a new table to contain that new set of values would also be created.
The problem I'm having is mapping out everything, in such a way that I can identify the value of each property, for each instance, of each object.
Any suggestions on what I might be missing, what I should be looking into, or any other solutions to the problem would be much appreciated.
Thanks!
Disclaimer: I'm a relativity new self taught programmer. Forgive any ignorance or shortcoming.
You could perhaps have something like this. I have not tested the code so please excuse any typos. The code is MS-SQL
CREATE TABLE tblUserDefinedEntity
(
UserDefinedEntityID INT NOT NULL PRIMARY KEY,
Name VARCHAR(255)
)
INSERT INTO tblUserDefinedEntity
VALUES
(1,'Person'),
(2,'Business')
-- properties each entity can have.
CREATE TABLE tblUserDefinedEntityProperty
(
UserDefinedEntityPropertyID INT NOT NULL PRIMARY KEY,
Name VARCHAR(255)
)
INSERT INTO tblUserDefinedEntityProperty
VALUES
(1,'FirstName'),
(2,'Surname'),
(3,'Address')
--maps properties to entities EG a person has a firstname
CREATE TABLE tblUserDefinedEntityPropertyMapping
(
ID INT NOT NULL PRIMARY KEY,
UserDefinedEntityID INT FOREIGN KEY REFERENCES tblUserDefinedEntityID(UserDefinedEntityID),
UserDefinedEntityPropertyID INT FOREIGN KEY REFERENCES tblUserDefinedEntityPropertyID(UserDefinedEntityPropertyID ),
)
-- a person has a firstname, surname and address, a business has a firstname and address
INSERT INTO tblUserDefinedEntityPropertyMapping
VALUES
(1,1,1),
(2,1,2),
(3,1,3),
(4,2,1),
(5,2,3)
--all the available values for each attribute, eg all the firstnames, surnames and addresses
CREATE TABLE tblValue
(
ValueID INT NOT NULL PRIMARY KEY,
Value VARCHAR(255),
UserDefinedEntityPropertyID INT FOREIGN KEY REFERENCES tblUserDefinedEntityProperty (UserDefinedEntityPropertyID),
)
INSERT INTO tblValue
VALUES
(1,'John',1),
(2,'James,1),
(3,'Jill',1),
(4,'Smith',2),
(5,'Jones',2),
(6,'123 Fake Street',3)
(7,'124 Fake Street',3)
--creating instances of your entities and assigning them values
CREATE TABLE tblDataEnty
(
DataItemID INT,
UserDefinedEntityPropertyMappingID INT FOREIGN KEY REFERENCES tblUserDefinedEntityPropertyMapping(UserDefinedEntityPropertyMappingID),
ValueID INT FOREIGN KEY REFERENCES tblValue(ValueID),
PRIMARY KEY (DataItemID, UserDefinedEntityPropertyMappingID)
)
-- we have added
-- john jones (no address)
-- james smith (124 fake street)
INSERT INTO tblDataEnty
VALUES
(1,1,1),
(1,2,5),
(2,1,2),
(2,2,4),
(2,3,7)

Stored procedure with multiple tables with foreign key

I am working on an event management project. In that project, I have a form in admin panel as add event which contains events name, category, sub-category, event admin etc and more. And in the database, I have different tables like event category, event sub-category.
And also I have a table that is cultural event which includes form fields and foreign key. I pass event catid, event sub-cat id.
On button click that cultural event is added.
I want to insert data in their tables and I want id that I gave in cultural event table.
On single click I want to insert this
How can I achieve this? Using a stored procedure?
CREATE TABLE EVENT_SCAT (ESUBCAT_ID INT NOT NULL PRIMARY KEY, ECAT_ID INT NOT NULL FOREIGN KEY REFERENCES EVENT_CAT(ECAT_ID), ESUBCAT_NAME VARCHAR(255) NOT NULL, )
create table EVENT_CAT (ECAT_ID INT NOT NULL IDENTITY PRIMARY KEY, ECAT_NAME VARCHAR(255)NOT NULL, EID INT NOT NULL FOREIGN KEY REFERENCES EVENTDETAILS(EID)
CREATE TABLE Cultural_E (c_ID INT NOT NULL IDENTITY PRIMARY KEY, cEVENT_NAME VARCHAR(255) NOT NULL, cE_SDATE DATE NOT NULL, cE_EDATE DATE NOT NULL, SE_RULES1 VARCHAR(MAX), SE_RULES2 VARCHAR(MAX), SE_RULES3 VARCHAR(MAX), cE_RULES4 VARCHAR(MAX), cE_EFEES INT, EID INT NOT NULL FOREIGN KEY REFERENCES EVENTDETAILS(EID), ECAT_ID INT NOT NULL FOREIGN KEY REFERENCES EVENT_CAT(ECAT_ID) )
and i have form in asp.net which includes all fields in single form but there are different tables with foreign keys. and i want id of ecat id and subcatid in last table i.e Cultural_e.
for ex:THESE ARE TABLE
eVENT_T
ID ENAME EADMIN
1 CULTURAL NIKHIL
E_CAT
ID ECAT_NAME E_iD
1 SINGING 1
event_scat
ID eCAT_iD ESUBCAT_NAME
1 1 SOLO
NOW I HAVE TABLE THAT IS CULTURAL_T
THESE TABLE HAVE ITS OWN FILEDS AS WELL AS FOREIGN KEY LIKE EID ,ECAT_ID AS YOU CAN SEE ABOVE
AND I HAVE FORM IN ASP.NET AND FORM CONTAINS TEXTBOX TO ENTER DATA OF ALL THESE TABLE.
SO PLZ TELL ME HOW TO ACHIEVE THIS
THANK YOU
As per my understanding of your question,try to use triggers rather than stored procedures if possible.
CREATE TRIGGER InsertEvents
AFTER INSERT ON EVENT_CAT
BEGIN
/* Insert Query to EVENT_SCAT */
/* Insert Query to cultural */
END

Getting the primary key back from a SQL insert with SQLite

I have a SQL table set that looks like this
create table foo (
id int primary key asc,
data datatype );
create table bar (
id int primary key asc,
fk_foo int,
foreign key(foo_int) references foo(id));
Now, I want to insert a record set.
insert into table foo (data) values (stuff);
But wait - to get Bar all patched up hunkydory I need the PK from Foo. I know this is a solved problem.
What's the solution?
try this
SELECT last_insert_rowid()

need help in primary key and foreign key

I need help in auto populating the primary key values in foreign key table while inserting data in foreign key table. For Example: I have created table:
create table Patient
(
PatientId int IDENTITY(1,1) primary key,
FirstName varchar(50),
SurName varchar(50),
Gender char(20),
)
Say 5 rows are there in this Patient Table:
Say First Row value is: 1, Priya, Kumari, Female
I have created the Guardians Table:
create table Guardians
(
GuardiansId int identity(1,1) primary key,
PatientId int foreign key references Patient(PatientId),
FirstName varchar(50),
SurName varchar(50),
Gender char(20),
RelationToPatient varchar(50),
)
In this table Insert operations are like this:
insert into Guardians(FirstName, SurName, Gender,RelationToPatient)values('Sumit','Kumar','Male','Wife')
While selecting the Guardians Table PatientId showing NULL values: My query is while inserting the values in Guardians Table PatientId should be auto Populated which will come from Patient Table...
My second problem is: How to create the Identity column as varchar. For example: suppose I want to increment my Guardians Table with 'GRD0001', 'GRD0002', 'GRD0003' like this...
Thanks,
S.D
Your question is not very clear - what exactly do you want to do??
When you insert something into the Guardians table, you want to automatically also insert it into the Patients table? I don't quite follow. Can you make a complete example, maybe??
If you need to capture the insert IDENTITY value from the Patient table, do this:
DECLARE #NewPatientID INT
INSERT INTO dbo.Patient(fields) VALUES(.......)
SET #NewPatientID = SCOPE_IDENTITY()
INSERT INTO dbo.Guardians(PatientId, ......) VALUES(#NewPatientID, ......)
As for your second question: leave you GuardiansId IDENTITY as it is (only an INT column can be an IDENTITY and you want to keep that - trust me!) and add a computed column to your table:
ALTER TABLE dbo.Guardians
ADD GuardianIDWithPrefix AS
'GDR' + RIGHT('0000' + CAST(GuardiansId AS VARCHAR(4)), 4) PERSISTED
Since it's a PERSISTED field, you can even index on it and use it like a normal field in every respect.
That should do the trick!