Relational SQL Server Databases - c#

I just registered here and this is my very first question. I hope I can explain myself clearly 'cause being a self-taught developer I don't quite speak the jargon.
My question: my project database holds employee information and has things like firstName, lastName, jobTitle, etc.. (static things).
My problem begins when I want to also start collecting all the clockIn & clockOut events of each employee. I can't think of an elegant way of adding these to my current database.
I don't know too much about databases but I think such things should either go in a totally different database or perhaps in a different table within the same database.
No idea which is the right answer.
The other thing is that these 2 databases or 2 tables need to somehow relate to each other somehow. When I select an employee from the list [data coming from the 1st DB or Tbl] and choose to view that specific employee's clock event history [data coming from the 2nd DB or Tbl] I should see that employee's clock in's & out's and NOT some other employee's clock events history.
A step-by-step tutorial is not necessary, but appreciated. Can you give me a quick explanation/outline of how this can be done ? If needed, I can add more details about
the project.
Thanks.

Like so:
CREATE TABLE Employees (
EmployeeId bigint IDENTITY(1,1) PRIMARY KEY,
FirstName nvarchar(50),
LastName nvarchar(50),
etc
)
CREATE TABLE EmployeeClocks ( -- rename as appropriate
EmployeeId bigint, -- foreign key
DateTime datetimeoffset(7),
ClockInType tinyint, -- values defined by an enum inside your program code
CONSTRAINT FK_EmployeeClocks_Employees FOREIGN KEY (EmployeeId) REFERENCES Employees (EmployeeId) ON DELETE CASCADE ON UPDATE CASCADE
)
Now for some queries:
Getting all of the clock-ins for an employee (assuming ClockInType = 1 for clock-ins, and 2 for clock-outs):
SELECT
DateTime
FROM
EmployeeClocks
INNER JOIN Employees ON EmployeeClocks.EmployeeId = Employees.EmployeeId
WHERE
Employees.FirstName = "Dick" AND
Employees.LastName = "Butt"

Read about database schema
You have to use two tables in a single database, Dai's answer showed the tables. just adding a few word if you re new to database then first read about it make a design idea than make database. because it very difficult to change in database when project is done.
Read some articles from here
database architecture
sql server database

Related

How should I handle one to many relationships to fill a data model

I'm trying to determine how I should handle a one to many relationship in my DB, when using the data to build a model in C#. Ideally, I'd like to make a single call to the DB. However, it seems that two (or more) calls might be required.
For simplicity, assume my tables look like this...
CREATE TABLE [dbo].[Users]
(
[userId] INT PRIMARY KEY IDENTITY(0,1),
[userName] NVARCHAR(500) NOT NULL
)
CREATE TABLE [dbo].[Tasks]
(
[taskId] INT PRIMARY KEY IDENTITY(0,1),
[description] NVARCHAR(1000) NOT NULL,
[userId] INT FOREIGN KEY REFERENCES [dbo].[Users](userId)
)
So each user can have many tasks. I have a stored procedure that will return the details of a user, that looks like this...
CREATE PROCEDURE [dbo].[sp_GetUserDetail]
#userId INT
AS
BEGIN
SELECT
[dbo].[Users].[userName] AS 'User',
[dbo].[Tasks].[description] AS 'Task Description'
FROM
[dbo].[Users]
INNER JOIN
[dbo].[Tasks]
ON
[dbo].[Tasks].[userId] = [dbo].[Users].[userId]
WHERE
[dbo].[Users].[userId] = #userId
END
This procedure returns as many rows, as tasks that are assigned to a user. The model I'm trying to fill, would look something like this.
public interface User
{
string Name { get; set; }
List<string> Tasks { get; set; }
}
I see my options as follows:
Use this code, and loop through the rows that are returned from the DB to build the Tasks list.
Call one stored procedure to return the data from the Users table, then another to get the data from the Tasks table.
Some (unknown to me magic) way to have a single stored procedure return all the data in a single row.
Some other option I don't even know about.
How is this problem typically handled by experienced Developers?
There are some language/framework specific answers which I won't cover (because C# is not my forte), but it's worth looking at "data binding", which is one of the features of the .Net framework. You could also look at ORM tools for C#.
The example you give - "how do I load child information for my parent" - is common, and you have to trade the number of database queries against the amount of data each query returns, and the complexity of your user interface code. For instance, if tasks have foreign keys to sub tasks (i.e. a self join), and task_type, and project_id, you have either:
1 query per table (your option 1): simplest to implement in the UI layer, simplest to implement in the database layer, but could easily cause dozens of database calls per screen.
1 query to retrieve all data for the screen (your option 2): single database hit, so should be faster, but complex UI and database logic; could potentially load the entire database into memory if you keep following foreign key relationships. Not all data may be necessary for the screen.
There is no "right" answer to this - it really depends on your application design.
However, there is an option you haven't mentioned (this is SQL Server-specific): a stored procedure can return multiple result sets. So, you could have one result set to provide the "header" data (user information), and one to provide task information.

Implement a "One-to-many" relationship with DataSets

I have two tables, one containing patient information, the other, the notes for each patient.
(One patient, many notes for a patient).
Given this, in the Designer (which you access by right-clicking on the chosen DataSet), how do I create a one-to-many relationship? I have never performed this before.
Secondly, for the patient notes table, how would I add a note to a patient record using SQL syntax? Note, this is not updating an existing one, but adding a completely new one to the patientNotes table using the unique patient ID number as the reference (so only that specific patient has that note added to them, not them and everyone else).
Very technically speaking, you don't need to do anything to create a one-to-many relationship. You just have to have the two tables set up as you have them and use them as you intend on using them. I work in data warehousing and unfortunately a great many of our relationships like this are not formalized with any sort of key or constraint.
The correct way to do it is to implement a foreign key constraint on the patient ID column on the patientNotes table. A FK will only allow you to insert data into patientNotes IF the patient ID exists in the patient table. If you would try to insert a note into your table that has a patient ID that doesn't exist in the patient table, the insert would fail and the SQL engine would give you an error. Note that the column on the patients table that you are creating the FK to must be a primary key.
Inserting data will really go as any other insert would:
INSERT INTO dbo.patientNotes (patientId, NoteText)
VALUES(4265, 'During his 8/14/2014 visit, Mr. Cottinsworth complained of chest pains. Evidently he has been wearing a lady''s corset to hide his large gut. Advised the very portly Mr. Cottinsworth to discontinue corset use'
You could toss that in a SP, put it in your code and use parameters for the patientId and NoteText, however you wanted to do it.
As far as doing this all in Visual Studio graphically, I can't be of much help there. I typically use the TSQL editor and type out what I want to do to the DB. I'm sure there are tutorials abound on how to set up FKs on Visual Studio.
Further reading:
http://msdn.microsoft.com/en-us/library/ms189049.aspx
http://www.scarydba.com/2010/11/22/do-foreign-key-constraints-help-performance/
what are the advantages of defining a foreign key

Persisting Object Graph to SQL Server in a single transaction

I am having an issue coming up with a solution that I think must be a common problem to be solved by anyone writing to a database. I keep thinking that there is an obvious solution that I'm overlooking and that's why I can't find an appropriate existing question here.
Imagine a situation where you need to let a user create a "Class", with "Students", and each "Student" is assigned one or more books. You have a well defined hierarchy, Class->Student->Book.
You have the following tables:
CREATE TABLE Classes (
ClassId int identity(1,1) primary key,
ClassName nvarchar(255)
)
CREATE TABLE Students (
StudentId int identity(1,1) primary key,
ClassId int,
StudentName nvarchar(255),
StudentImage image
)
CREATE TABLE StudentBooks (
StudentBookId int identity(1,1) primary key,
StudentId int,
BookName nvarchar(255)
)
With this contrived scenario, what are my options for saving this entire graph of new objects, while letting SQL server assign the identity columns, and keeping it all in one transaction? Assuming that a class has maybe 30 students, and each student has several books assigned.
I could create a transaction and make a separate call for each row in each table, returning SCOPE_IDENTITY for each new parent object so I can save each child while keeping RI intact.
I could use XML. I would like to avoid that, as the graph includes a byte array.
Any other options? I thought about passing each level of the hierarchy in a table parameter. I'm not sure how or if that would work. (Wouldn't I have to define a table type for each of my tables, essentially duplicating the schema?)
I can use SQL server 2012 for this.
Thank you!
You can use Entity Framework to achieve what you want.
There are lots of tutorials out there, but a good starting point is this one:
MSDN on getting started with Entity Framework
or the linked page
MSDN overview page on getting started
I would recommend the EDMX approach for your use-case.

confusion over relationships

Hey guys I have a confusing question, I have a user table and it stores all the usual data for a user that you would expect but im trying to figure out how a user could add another user?
Sounds strange but each user in the User table has his own UI which is UserID how could I add another table where UserID can have a relationship with another UserID?
I will give the answer to those that could take the time to upload a table diagram and who can help with some examples for sqlsyntax related to this question, i.e how would I right the syntax for the above question if I wanted to display all the UserIDs friends on a page. How would I add a friend.
You just need another table similar to the Pictures and wallposting table. You just need to be able to record many friend id's for one user id (one to many)
eg:
The query to then get friends would be:
DECLARE #UserID AS BIGINT
SET #UserID = 123
SELECT [friends].*
FROM [friends]
where [parentuserid]=#UserID#
to Insert a Friend:
DECLARE #UserID AS BIGINT
DECLARE #FriendID AS BIGINT
SET #UserID = 123
SET #FriendID = 321
INSERT INTO [Friends]
(
[ParentUserID],
[ChildUserID]
)
VALUES
(
#UserID,
#FriendID
)
Code to insert it example:
private void Test()
{
string Query =
#"INSERT INTO [Friends]
(
[ParentUserID],
[ChildUserID]
)
VALUES
(
#UserID,
#FriendID
)";
using ( SqlConnection oSqlConnection = new SqlConnection( "connect string" ) )
{
oSqlConnection.Open();
using (SqlCommand oSqlCommand = new SqlCommand(Query,oSqlConnection))
{
oSqlCommand.Parameters.AddWithValue("#UserID", Session["UserID"]);
oSqlCommand.Parameters.AddWithValue("#FriendID", Session["FriendID"]);
oSqlCommand.ExecuteNonQuery();
}
}
}
Where would you get your friend ID from? what is the process for adding friends? do you search for them and select them from a list?
You just need a many to many relationship.
Create Table Friend(
UserId int,
FriendId int,
Constraint pk_friends Primary Key (UserId, FriendId),
Constraint fk_friend_user Foreign Key (UserId) References User(UserId),
Constraint fk_friend_friend Foreign Key (FriendId) References User(UserId)
)
Your asking a bit much with the diagrams etc.... for me at least.
It depends on the kind of relationship, one to one, it will be another Column in your user table. If it is many to many you'll need a junction table, with two columns UserIDA, UserIDB. Depending why you need the relationship.
I think you have a simple requirement of a User Referring Other user to join. If that is the case then you can simply have one more column ReferenceUserID in User Table and whenever a new user refers another user then simply add him with a UserID of referring user. If he isn't a referred user then by default it will be NULL.
Later for retrieval you can use a Self Join.
Update:
For Friend (many to many relationship) you should look at following Question at StackOverflow
Database design: Best table structure for capturing the User/Friend relationship?
UserRelationship
====
RelatingUserID
RelatedUserID
Type[friend, block, etc]
A similar approach is used by Facebook where they have a kind of Cross join Table for relation between Friends.

How can I Insert/Update into two related tables in one command?

A database exists with two tables
Data_t : DataID Primary Key that is
Identity 1,1. Also has another field
'LEFT' TINYINT
Data_Link_t : DataID PK and FK where
DataID MUST exist in Data_t. Also has another field 'RIGHT' SMALLINT
Coming from a microsoft access environment into C# and sql server I'm looking for a good method of importing a record into this relationship.
The record contains information that belongs on both sides of this join (Possibly inserting/updating upwards 5000 records at once). Bonus to process the entire batch in some kind of LINQ list type command but even if this is done record by record the key goal is that BOTH sides of this record should be processed in the same step.
There are countless approaches and I'm looking at too many to determine which way I should go so I thought faster to ask the general public. Is LINQ an option for inserting/updating a big list like this with LINQ to SQL? Should I go record by record? What approach should I use to add a record to normalized tables that when joined create the full record?
Sounds like a case where I'd write a small stored proc and call that from C# - e.g. as a function on my Linq-to-SQL data context object.
Something like:
CREATE PROCEDURE dbo.InsertData(#Left TINYINT, #Right SMALLINT)
AS BEGIN
DECLARE #DataID INT
INSERT INTO dbo.Data_t(Left) VALUES(#Left)
SELECT #DataID = SCOPE_IDENTITY();
INSERT INTO dbo.Data_Link_T(DataID, Right) VALUES(#DataID, #Right)
END
If you import that into your data context, you could call this something like:
using(YourDataContext ctx = new YourDataContext)
{
foreach(YourObjectType obj in YourListOfObjects)
{
ctx.InsertData(obj.Left, obj.Right)
}
}
and let the stored proc handle all the rest (all the details, like determining and using the IDENTITY from the first table in the second one) for you.
I have never tried it myself, but you might be able to do exactly what you are asking for by creating an updateable view and then inserting records into the view.
UPDATE
I just tried it, and it doesn't look like it will work.
Msg 4405, Level 16, State 1, Line 1
View or function 'Data_t_and_Data_Link_t' is not updatable because the modification affects multiple base tables.
I guess this is just one more thing for all the Relational Database Theory purists to hate about SQL Server.
ANOTHER UPDATE
Further research has found a way to do it. It can be done with a view and an "instead of" trigger.
create table Data_t
(
DataID int not null identity primary key,
[LEFT] tinyint,
)
GO
create table Data_Link_t
(
DataID int not null primary key foreign key references Data_T (DataID),
[RIGHT] smallint,
)
GO
create view Data_t_and_Data_Link_t
as
select
d.DataID,
d.[LEFT],
dl.[RIGHT]
from
Data_t d
inner join Data_Link_t dl on dl.DataID = d.DataID
GO
create trigger trgInsData_t_and_Data_Link_t on Data_t_and_Data_Link_T
instead of insert
as
insert into Data_t ([LEFT]) select [LEFT] from inserted
insert into Data_Link_t (DataID, [RIGHT]) select ##IDENTITY, [RIGHT] from inserted
go
insert into Data_t_and_Data_Link_t ([LEFT],[RIGHT]) values (1, 2)

Categories