Create a stored procedure for a table named X - sql

CREATE TABLE Persons
(
ID int NOT NULL,
ModifiedDate datetime,
FirstName varchar(50),
LastName varchar(50),
EMail varchar(30),
PhoneNumber varchar(15),
PRIMARY KEY (ID)
);
GetX (int IDX)
if the parameter is null returns all the rows of the table ordered by ModifiedDate field in descending order
otherwise returns just the row that matches the ID

What you are wanting is a "catch all" query. For SQL Server, this can be done a couple of ways. Aaron Bertrand writes about it here.
create procedure GetX (#IDX int = null)
as
select
ID
,ModifiedDate
,FirstName
,LastName
,EMail
,PhoneNumber
from Persons
where #IDX is null or ID = #IDX
order by ModifiedDate desc
Then
exec GetX #IDX = 4;
exec GetX #IDX = null;

Related

How to Modify a Value using stored procedure

I'm new to SQL and I'm stuck. If anyone could please help me out.
I have a stored procedure modifyMobileNo to change a mobile number, where ID and MobileNo are the parameters. Change Sarah Furgerson's number to 3246568413
Table columns:
ID INT NOT NULL
FirstName NVARCHAR(20) NOT NULL
LastName NVARCHAR(20) NOT NULL
HouseUnitLotNum NVARCHAR(5) NOT NULL
Street NVARCHAR(50) NOT NULL
Suburb NVARCHAR(50) NOT NULL
State NVARCHAR(3) NOT NULL
PostCode NCHAR(4) NOT NULL
MobileNo NCHAR(10) NULL
DateOfBirth DATE NOT NULL
Gender NCHAR(10) NOT NULL
Ref NVARCHAR(4) NOT NULL
CREATE PROCEDURE modifyMobileNo #ID INT, #MobileNo NCHAR(10)
AS
SELECT ID, Firstname, LastName, MobileNo
FROM Table
WHERE ID = #ID AND MobileNo = #MobilePNo
BEGIN
Do I need to add more parameters? Sorry, so confused.
Not sure where to start.
BEGIN
SET NOCOUNT ON;
UPDATE Table
SET ID = #ID,
MobileNo = #MobileNo
WHERE
FirstName = #FirstName
AND LastName = #LastName
END
seems like it should be something simple like -
CREATE PROCEDURE modifyMobileNo #ID INT, #MobileNo NCHAR(10)
AS
BEGIN
UPDATE Table
SET MobileNo = #MobileNo
WHERE ID = #ID
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.

Create SQL Function view with User ID and Date range

As I title says, I need to create a Function View of two tables.
Below are the SQL Tables
CREATE TABLE User_Specialist(
ID_User_Specialist INT NOT NULL,
Name_User_Specialist VARCHAR(50) NOT NULL,
CONSTRAINT PK_ID_User_Specialist PRIMARY KEY(ID_User_Specialist),
GO
CREATE TABLE Incident(
ID_Incident INT IDENTITY(1,1) NOT NULL,
Incident_Creation_Date DATETIME NULL,
Assigned_Specialist INT NULL,
CONSTRAINT FK_Assigned_Specialist FOREIGN KEY (Especialista_Asignado) REFERENCES Usuario_Especialista(ID_Usuario_Especialista),
GO
Based on the previous information, I need the function to display Assign Specialist and the dates that the Incident was created.
Right know this is what I got:
CREATE FUNCTION View_Date (#ID_User_Incident INT)
RETURNS INT
AS
BEGIN
DECLARE #Total_Incidents INT
SELECT #Total_Incidents = COUNT(ID_Incident)
FROM Incidents i, User_Specialist u
WHERE i.ID_Incident = u.ID_User_Specialist AND u.ID_User_Specialist =#ID_User_Incident
RETURN (#Total_Incidents)
END
GO
DECLARE #Specialist_ID int;
EXEC #Specialist_ID = [dbo].View_Date
#ID_Incidentes_Usuarios = 5;
SELECT #Specialist_ID AS 'Assigned Specialist Incidents'
GO
The only thing missing is the dates range.
I believe you changed your table and field names to English from Spanish. You have missed some of them and there were some missing parenthesis. As much as I understand I changed them to understand better.
CREATE TABLE User_Specialist
(
ID_User_Specialist INT NOT NULL,
Name_User_Specialist VARCHAR(50) NOT NULL
CONSTRAINT PK_ID_User_Specialist PRIMARY KEY(ID_User_Specialist)
)
GO
CREATE TABLE Incident
(
ID_Incident INT IDENTITY(1,1) NOT NULL,
Incident_Creation_Date DATETIME NULL,
Assigned_Specialist INT NULL
CONSTRAINT FK_Assigned_Specialist FOREIGN KEY (Assigned_Specialist) REFERENCES User_Specialist(ID_User_Specialist)
)
GO
If you want to see multiple columns or rows as result you need to use Table-valued Function. I have created sample query from your table and prepared function. you can change it with what you want.
CREATE FUNCTION dbo.FN_ViewDate
(
#ID_User_Incident INT
)
RETURNS #Result TABLE
(
TotalIncidents INT
,FirstIncidentDate DATETIME
,LastIncidentDate DATETIME
)
AS
BEGIN
INSERT INTO #Result
SELECT COUNT(ID_Incident)
,MIN(Incident_Creation_Date)
,MAX(Incident_Creation_Date)
FROM Incident I
LEFT JOIN User_Specialist U ON I.Assigned_Specialist = U.ID_User_Specialist
WHERE I.Assigned_Specialist = #ID_User_Incident
RETURN
END
GO
I think this query can help you.
declare #count int = 0 , #dates varchar(200) =''
SELECT #count+=1 , #dates +=' '+ i.Incident_Creation_Date
FROM Incidents i, User_Specialist u
WHERE i.ID_Incident = u.ID_User_Specialist AND u.ID_User_Specialist =#ID_User_Incident
select #count as [count] ,#dates [incidentDates]

Insert into multiple(7) tables with no duplicates

Trying to create a query/SP that will take data from one table and insert it into multiple tables. I have one main table that everything is put into at the beginning like a temp table.
Temp table
CREATE TABLE Employee
(
userID INT IDENTITY(1,1) NOT NULL,
userName VARCHAR(50) NULL,
FirstName VARCHAR(50) NULL,
LastName VARCHAR(50) NUll,
UserPassWd VARCHAR(50) NULL,
EmailId VARCHAR(100) NULL
CONSTRAINT PK_Employee PRIMARY KEY (userID)
)
Than when employee is verified it will be split up into multiple tables that only need a field or two from the temp table as needed. The UserEmail table I have listed below is one of the tables. I'm trying to get it to work for one table right now and then I'm guessing i will just copy the insert part and change the table name and attributes to the new tables
Here is what i have so far.
DECLARE #EMAIL VARCHAR(100)
DECLARE #USERID INT
SELECT #USERID = userID
,#EMAIL = EmailId
FROM Employee
WHERE userID = 1004
INSERT INTO UserEmail
(
EmailAddress
,EmailTypeID
,ExternalUserID
,Active
,CreatedByID
,CreatedDate
,UpdatedByID
,UpdatedDate
)
SELECT #EMAIL -- Email Address
,1 -- Email Type
,1 -- ExternalUserID
,1 -- Active
,1 -- CreatedByID
,CURRENT_TIMESTAMP -- CreatedDate
,1
,CURRENT_TIMESTAMP -- UpdatedDate
FROM Employee X
WHERE 1=1
AND X.userID = '####'-- INSERT USERID HERE for testing
This will insert the record into the UserEmail table but will create duplicate users, which i cant have so I tried adding this but it doesn't do what I want it to do.
WHERE 1=1
AND NOT EXISTS(
SELECT userID
FROM Employee
WHERE userID = 1004
)
Any guidance or help would be much appreciated. Thank You!
If you only like NOT to insert to UserEmail if user already exists just extend
INSERT INTO UserEmail ....
SELECT ....
FROM ....
WHERE ..
AND NOT EXISTS (select 1 from UserEmail where EmailAddress = X.emailAddress)
Otherwise review MERGE syntax (https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql)

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.