Microsoft SQL - Stored Procedure to transfer an employee - sql

I want to create a stored procedure that transfers an employee from the current team to another team. So far I've done this:
CREATE OR ALTER PROC pr_EmployeeTeam #IDTeam1 int, #IDTeam2 int
AS
BEGIN
DECLARE #NIC int
SELECT #IDTeam1 = IDTeam from StuffTeams
SELECT #IDTeam2 = IDTeam from StuffTeams
UPDATE StuffTeams SET IDTeam = #IDTeam1 WHERE NIC = #NIC
UPDATE StuffTeams SET IDTeam = #IDTeam2 WHERE NIC = #NIC
END
EXEC pr_EmployeeTeam 2,5
And my StuffTeam table:
CREATE TABLE StuffTeams(
IDStuffTeam nvarchar(30) NOT NULL,
IDTeam int NOT NULL,
NIC int NOT NULL,
DateStart date NOT NULL,
DateFinish date NOT NULL,
CONSTRAINT PK_Stuff PRIMARY KEY (IDStuffTeam),
CONSTRAINT FK_sTeam FOREIGN KEY (IDTeam) REFERENCES Teams (IDTeam),
CONSTRAINT FK_sNIC FOREIGN KEY (NIC) REFERENCES Employees (NIC),
)
Inside of StuffTeams I have 30 values but when I exec the code says
0 rows affacted
Many thanks
UPDATE
CREATE PROC sp_UpdateTeam
#TeamID int,
#NIC int
AS
BEGIN
update StuffTeams SET IDTeam = #TeamID
WHERE NIC = #NIC
END
EXEC sp_UpdateTeam 5,54321
This solved my problem! Thanks

Based upon your requirement, I have updated your proc as shown below:
CREATE OR ALTER PROC pr_EmployeeTeam #IDTeam1 int, #IDTeam2 int
AS
BEGIN
DECLARE #NIC int
SELECT #NIC = IDTeam from StuffTeams WHERE IDTeam = #IDTeam1
UPDATE StuffTeams SET IDTeam = #IDTeam2 WHERE NIC = #NIC
END
EXEC pr_EmployeeTeam 2,5

Related

how to add a database constraint 18 or above

i have create a table and I need to add a database constraint "A customer with an age under 18 cannot rent a movie rated “18 or above”." How do I use SQL to add this in my table
You can use a trigger. When you want to enter information in the system to order a movie, do not allow the user to create a record if the age is less than the minimum required.
The following code snippet implements this scenario completely.
CREATE TABLE Customers
(
ID int identity,
FirstName nvarchar(100),
LastName nvarchar(100),
Age int,
primary key(ID))
CREATE TABLE Films
(
ID int identity,
FilmName nvarchar(100),
MinimumAge int,
primary key(ID))
CREATE TABLE OrderFilms
(
ID int identity,
CustomerID int,
FilmID int,
primary key(ID),
foreign key(CustomerID) references Customers,
foreign key(FilmID) references Films)
create trigger trigger_for_insert_into_OrderFilms
On OrderFilms
For Insert
AS
Declare #film int
Declare #customer int
Declare #filmage int
Declare #customerage int
set #film = (SELECT top 1 FilmID FROM inserted)
set #customer = (SELECT top 1 CustomerID FROM inserted)
set #filmage = (SELECT MinimumAge FROM Films WHERE ID = #film)
set #customerage = (SELECT Age FROM Customers WHERE ID = #customer)
IF(#filmage > 18 AND #customerage < 18)
BEGIN
PRINt 'ERROR, CUSTOMER AGE THE CUSTOMER IS YOUNG'
RollBack
END

How to move hierarchyid subtree if the new parent has already got children?

I guess the problem is described in the title pretty well. I've got a table like this:
CREATE TABLE [Employees] (
[Id] INT identity(1, 1) PRIMARY KEY
,[Hid] HIERARCHYID NOT NULL
,[Name] VARCHAR(50) NULL
,[Secondname] VARCHAR(50)
,[Surname] VARCHAR(50)
,[BossId] INT FOREIGN KEY REFERENCES [Employees]([Id])
,[PositionId] INT FOREIGN KEY REFERENCES [Positions]([Id])
,[DepartmentId] INT FOREIGN KEY REFERENCES [Departments]([Id])
,[RecruitDate] DATE NOT NULL
);
And I need to change employee's boss from one to another. Obviously, there is a nice solution - GetReparentedValue(), and I used this example that seemed to be exactly what I needed.
But this solution happens to be not working. Hid.GetAncestor(1) is equal to previous BossHid. Probably, the problem is that it can't work well if new parent already got children. That really upsets me. Does it mean I need to write recursive CTE on my own?
Here is the code that was supposed to be working but it didn't:
CREATE PROCEDURE UpdateEmployee #Id INT
,#Name VARCHAR(50)
,#Secondname VARCHAR(50)
,#Surname VARCHAR(50)
,#BossId INT
,#PosId INT
,#DepId INT
,#Rdate DATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE #BossExist INT
,#OldBossHid HIERARCHYID
,#NewBossHid HIERARCHYID
,#LastHid HIERARCHYID;
SELECT #BossExist = count(*)
FROM dbo.Employees
WHERE [Hid] = HIERARCHYID::GetRoot();
IF #BossExist != 0
AND #BossId IS NULL
RETURN;
SELECT #OldBossHid = (
SELECT [Hid].GetAncestor(1)
FROM dbo.Employees
WHERE #Id = [Id]
);
SELECT #NewBossHid = (
SELECT [Hid].GetAncestor(1)
FROM dbo.Employees
WHERE #BossId = BossId
);
SELECT #LastHid = #NewBossHid.GetDescendant(MAX([Hid]), NULL)
FROM dbo.Employees
WHERE [Hid].GetAncestor(1) = #NewBossHid;
UPDATE dbo.Employees
SET [Hid] = [Hid].GetReparentedValue(#OldBossHid, #NewBossHid)
WHERE [Hid].IsDescendantOf(#OldBossHid) = 1;
UPDATE dbo.Employees
SET [Name] = #Name
,[Secondname] = #Secondname
,[Surname] = #Surname
,[BossId] = #BossId
,[PositionId] = #PosId
,[DepartmentId] = #DepId
,[RecruitDate] = #Rdate
WHERE #Id = Id;
END
GO
Thank you.

How to trigger a table to change the value of another table column

I've created three tables.
CREATE TABLE Clients
(
ClientID INT IDENTITY(1,1) PRIMARY KEY,
First_Name VARCHAR(50) NOT NULL,
Last_Name VARCHAR(50) NOT NULL,
)
CREATE TABLE Reservation
(
ReservationID INT IDENTITY(1,1) PRIMARY KEY,
ClientID INT FOREIGN KEY (ClientID) REFERENCES Clients(ClientID),
Reservation_paid VARCHAR(3) DEFAULT 'NO',
)
CREATE TABLE Payment
(
Payment_ID INT IDENTITY(1,1) PRIMARY KEY,
ClientID INT FOREIGN KEY (ClientID) REFERENCES Clients(ClientID),
ReservationID INT FOREIGN KEY (ReservationID) REFERENCES Reservation(ReservationID),
)
I would like to change the value of the column Reservation_paid to YES at the Reservation table whenever the Client does pay the reservation, and i want to do it automatically with trigger.
Example: If the ClientID at the Reservation table exists at the Payment table automatically the value of the Reservation_paid will set to YES.
Thank you in advance.
CREATE TRIGGER trgAfterInsert ON [dbo].[Payment]
FOR INSERT
AS
declare #ClientID int;
select #ClientID =i.ClientID from inserted i;
if update(ClientID)
UPDATE Reservation set Reservation_paid='Yes' WHERE
ClientID=#ClientID;
--PRINT 'AFTER INSERT trigger fired.'
After Insert Trigger should do something like this
UPDATE R
SET Reservation_paid = 'Yes'
FROM reservation R
WHERE EXISTS (SELECT 1
FROM INSERTED I
WHERE I.clientid = R.clientid
AND I.reservationid = R.reservationid)
CREATE TRIGGER trgAfterInsert ON [dbo].[Payment]
FOR INSERT
AS
declare #ClientID int;
select #ClientID =i.ClientID from inserted i;
insert into Reservation(ClientID,Reservation_paid)
values(#ClientID,'Yes');
--PRINT 'AFTER INSERT trigger fired.'
GO
Write a trigger that will work on table Reservation after any insert or update on ClientId column of table Payment. Then match the ClientID with ClientID column of Reservation table and update the corresponding Reservation_paid to YES.
Edit:
The trigger will be like this
CREATE TRIGGER `UpdateReservation_paid` AFTER INSERT OR UPDATE ON `Payment`
FOR EACH ROW BEGIN
AS
begin
update Reservation
SET Reservation_paid='YES'
Where NEW.ClientID = Reservation.ClientID
and NEW.ReservationID = Reservation.ReservationID
end

Adding CHECK constraint conflicts with IS NULL

I got a problem when I try to add a constraint to one of my tables. I want to check in a function so that a state is true and then returns 1 or 0 depending on if it is true. But in the function I check if a value in a column is NULL and that causes the error
The ALTER TABLE statement conflicted with the CHECK constraint "chk_StateFinished". The conflict occurred in database "databaseName", table "dbo.Participation".
the Function looks like this
CREATE FUNCTION CheckStateFinished(#StudentID varchar(10), #CourseID varchar(10), #CoursePeriod varchar(10),
#SchoolYear int, #State varchar(15)) RETURNS int
AS BEGIN
DECLARE #Grade varchar(1)
SELECT #Grade = Grade FROM Participation WHERE StudentID = #StudentID AND CourseID = #CourseID AND CoursePeriod = #CoursePeriod AND SchoolYear = #SchoolYear
RETURN CASE WHEN #State = 'Avslutad' AND #Grade = 'U' OR #Grade IS NULL THEN 0
ELSE 1
END
END
And the Add Check Constraint looks like this:
ALTER TABLE Participation ADD CONSTRAINT chk_StateFinished CHECK (dbo.CheckStateFinished(StudentID, CourseID, CoursePeriod, SchoolYear, _State) = 1)
What should I do instead of IS NULL in the Function or should i do something else?
The issue is not in function CheckStateFinished but with existing data in table Participation on which CHECK CONSTRAINT is to be added. When we add Check constraint to an existing table using Alter table command by default it applies to both existing data and any new data.
There might be some row in table Participation where for given StudentID, CourseID, CoursePeriod, SchoolYear, _State parameters function is evaluating to 0 and hence Check constraint is getting failed.
In such a case use WITH NOCHECK option so that Check constraint applies only to new data.
create table Participation (Grade varchar(1),StudentID varchar(10), CourseID varchar(10), CoursePeriod varchar(10), SchoolYear int, [State] varchar(15))
insert into Participation values ('A','Student1','Course1','CourseP1',2013,'Avslutad')
-- for this row check constraint will work fine.
insert into Participation values ('U','Student2','Course1','CourseP1',2013,'Avslutad') -- for this row check constraint will fail.
insert into Participation values (NULL,'Student3','Course1','CourseP1',2013,'Avslutad')
-- for this row check constraint will fail.
insert into Participation values ('U','Student4','Course1','CourseP1',2013,'XYZ')
-- for this row check constraint will work fine.
--insert into Participation values ('A','Student5','Course1','CourseP1',2013,'XYZ')
Go
CREATE FUNCTION CheckStateFinished(#StudentID varchar(10), #CourseID varchar(10), #CoursePeriod varchar(10),
#SchoolYear int, #State varchar(15)) RETURNS int
AS BEGIN
DECLARE #Grade varchar(1)
SELECT #Grade = Grade FROM Participation WHERE StudentID = #StudentID AND CourseID = #CourseID AND CoursePeriod = #CoursePeriod AND SchoolYear = #SchoolYear
RETURN CASE WHEN #State = 'Avslutad' AND #Grade = 'U' OR #Grade IS NULL THEN 0
ELSE 1
END
END
Go
ALTER TABLE Participation WITH NOCHECK -- add this and your constraint will work.
ADD CONSTRAINT chk_StateFinished CHECK (dbo.CheckStateFinished('Student3','Course1','CourseP1',2013,'Avslutad') = 1)
Go

SQL problem: same column in one

hy!
I have 2 tables and in each I have a column date, I need to make a single table with the information from all 2 tables with a column date which i want to get from the 3 tables,but in the same column
i tried the following code, but didn`t work
CREATE FUNCTION dbo.GetContactInformation(#id int)
RETURNS #retActivityInformation TABLE
(
ClientID int NOT NULL,
ActivityDate datetime NULL,
Tipe nvarchar(50) NULL,
Number nvarchar(50) NULL,
Value int NULL,
Statu nvarchar(50) NULL,
PRIMARY KEY CLUSTERED (clientID ASC)
) AS
BEGIN
DECLARE
#ClientID int,
#ActivityDate datetime,
#Tip nvarchar(50),
#Number nvarchar(50),
#Value int,
#Statu nvarchar(50);
SELECT
#ClientID = ClientID,
#ActivityDate = ActivityDate,
#Number = Number,
#Value = Value,
#Statu = Statu
FROM Fa,Pay
WHERE ID = #id;
SET #ActivityDate =
CASE
WHEN EXISTS(SELECT Fa.DataEmitere FROM Fa AS e
WHERE e.ID = #id)
THEN 'Fa'
WHEN EXISTS(SELECT Pay.Data FROM Pay AS bec
WHERE bec.ID = #id)
THEN 'Pay'
END;
IF #id IS NOT NULL
BEGIN
INSERT #retActivityInformation
SELECT #clientID, #ActivityDate, #Number, #Value,#Statu;
END;
RETURN;
END;
Just prefix the field with the database name. I am going to assume the date you actually mean is ActivityDate. If you want to SELECT/INSERT using this field you will need to prefix with Fa or Pay so it would be Fa.ActivityDate or Pay.ActivityDate.
If this is not the field then we'd need more info.
Use the column by specifying the table name as below:-
CREATE FUNCTION dbo.GetContactInformation(#id int)
RETURNS #retActivityInformation TABLE
(
ClientID int NOT NULL,
ActivityDate datetime NULL,
Tipe nvarchar(50) NULL,
Number nvarchar(50) NULL,
Value int NULL,
Statu nvarchar(50) NULL,
PRIMARY KEY CLUSTERED (clientID ASC)
) AS
BEGIN
DECLARE
#ClientID int,
#ActivityDate datetime,
#Tip nvarchar(50),
#Number nvarchar(50),
#Value int,
#Statu nvarchar(50);
SELECT
#ClientID = ClientID,
#ActivityDate = Fa.ActivityDate,
#Number = Number,
#Value = Value,
#Statu = Statu
FROM Fa,Pay
WHERE ID = #id;
SET #ActivityDate =
CASE
WHEN EXISTS(SELECT Fa.DataEmitere FROM Fa AS e
WHERE e.ID = #id)
THEN 'Fa'
WHEN EXISTS(SELECT Pay.Data FROM Pay AS bec
WHERE bec.ID = #id)
THEN 'Pay'
END;
IF #id IS NOT NULL
BEGIN
INSERT #retActivityInformation
SELECT #clientID, #ActivityDate, #Number, #Value,#Statu;
END;
RETURN;
END;
See the middle part here:
CREATE FUNCTION dbo.GetContactInformation(#id int)
RETURNS #retActivityInformation TABLE
(
ClientID int NOT NULL,
ActivityDate datetime NULL,
Tipe nvarchar(50) NULL,
Number nvarchar(50) NULL,
Value int NULL,
Statu nvarchar(50) NULL,
PRIMARY KEY CLUSTERED (clientID ASC)
) AS
BEGIN
DECLARE
#ClientID int,
#ActivityDate datetime,
#Tip nvarchar(50),
#Number nvarchar(50),
#Value int,
#Statu nvarchar(50);
SELECT
#ClientID = ClientID,
#ActivityDate = ActivityDate,
#Number = Number,
#Value = Value,
#Statu = Statu
FROM Fa,Pay
WHERE ID = #id;
SET #ActivityDate = ISNULL(
(SELECT top 1 Fa.DataEmitere FROM Fa AS e WHERE e.ID = #id),
(SELECT top 1 Pay.Data FROM Pay AS bec WHERE bec.ID = #id))
IF #id IS NOT NULL
BEGIN
INSERT #retActivityInformation
SELECT #clientID, #ActivityDate, #Number, #Value,#Statu;
END;
RETURN;
END;
Essentially, instead of testing to see if the data EXISTS just to get the field name, get the data directly.