How can i optimize this stored procedure Without Join - sql

I have a situation like this to a instant search but this query have more NOT IN check
ALTER PROC [dbo].[DPR_SP_GetEmployeeDetailsByKeyword]
#keyword varchar(10),
#hotelId int
AS
BEGIN
SELECT EmployeeDetails.EmployeeId,EmployeeDetails.SageEmployeeId,EmployeeDetails.FirstName,EmployeeDetails.LastName
FROM EmployeeDetails
WHERE (EmployeeDetails.EmployeeId NOT IN ( SELECT EmployeeWorksIn.EmployeeId
FROM EmployeeWorksIn
WHERE EmployeeWorksIn.HotelId=#hotelId
)
AND
EmployeeDetails.EmployeeId LIKE #keyword+'%')
OR
(EmployeeDetails.EmployeeId NOT IN ( SELECT EmployeeWorksIn.EmployeeId
FROM EmployeeWorksIn
WHERE EmployeeWorksIn.HotelId=#hotelId
)
AND
OR
(EmployeeDetails.EmployeeId NOT IN ( SELECT EmployeeWorksIn.EmployeeId
FROM EmployeeWorksIn
WHERE EmployeeWorksIn.HotelId=#hotelId
)
AND
EmployeeDetails.DateOfBirth LIKE #keyword+'%')
How can I optimise this query
Thanks

You cam rewrite this as
alter proc dbo.DPR_SP_GetEmployeeDetailsByKeyword
#keyword varchar(10),
#hotelId int
As
Select
e.EmployeeId,
e.SageEmployeeId,
e.FirstName,
e.LastName
From
EmployeeDetails e
Left Outer Join
EmployeeWorksIn w
on e.EmployeeId = w.EmployeeId and w.HotelId = #hotelId
Where
w.EmployeeID Is Null And (
e.EmployeeId Like #keyword+'%' Or
e.Something Like #keyword+'%' Or -- appears to be missing from question
e.DateOfBirth Like #keyword+'%'
);
after that you'll be looking at indexing to speed things up.

Related

how to execute stored procedure in sql using join

ALTER procedure [dbo].[SPEmployeeInformation]
#searchText nvarchar(100)
as
begin
select EmployeeInformation.LineId, FirstName, MidName, FatherName, MotherName, dob, MeritalStatus, ParmanentAddress,
DepartmentMaster.DepartmentName, DesignationMaster.Designation, EmployeeCategory.EmployeeCategory, Salary.Salary
from EmployeeInformation
inner join DepartmentMaster on EmployeeInformation.DepartmentName=DepartmentMaster.DepartmentLineId
inner join DesignationMaster on EmployeeInformation.Designation=DesignationMaster.DesignationLineId
inner join EmployeeCategory on EmployeeInformation.EmployeeCategory=EmployeeCategory.EmployeeCategoryLineId
inner join Salary on EmployeeInformation.LineId=Salary.EmployeeLineID
where FirstName+MidName+FatherName+MotherName+MeritalStatus+ParmanentAddress+
DepartmentMaster.DepartmentName+DesignationMaster.Designation+EmployeeCategory.EmployeeCategory like '%'+#searchText+'%'
end
I just try to test with your scenario with sample data and its works. That means you doing wrong in query like column name or int datatype value etc.
Without sample data we can't do, just check the concept below.
declare #table table (fname varchar(200), lname varchar(200))
declare #patientName varchar(200) ='john'
insert into #table values ('doe', 'john'),('ritu', 'pawar'),('Vogue', 'jani')
select * from #table where fname+lname like '%'+#patientName+'%'
set #patientName ='ej'
select * from #table where fname+lname like '%'+#patientName+'%'
Output are
First query return below
fname lname
doe john
Second query return below
fname lname
doe john
Vogue jani
Using MS SQL
Create procedure [dbo].[SPEmployeeInformation]
#searchText nvarchar(100)
as
begin
select EmployeeInformation.LineId, FirstName, MidName, FatherName, MotherName, dob, MeritalStatus, ParmanentAddress,
DepartmentMaster.DepartmentName, DesignationMaster.Designation, EmployeeCategory.EmployeeCategory, Salary.Salary
from EmployeeInformation
inner join DepartmentMaster on EmployeeInformation.DepartmentName=DepartmentMaster.DepartmentLineId
inner join DesignationMaster on EmployeeInformation.Designation=DesignationMaster.DesignationLineId
inner join EmployeeCategory on EmployeeInformation.EmployeeCategory=EmployeeCategory.EmployeeCategoryLineId
inner join Salary on EmployeeInformation.LineId=Salary.EmployeeLineID
where FirstName+MidName+FatherName+MotherName+MeritalStatus+ParmanentAddress+ DepartmentMaster.DepartmentName+DesignationMaster.Designation+EmployeeCategory.EmployeeCategory like '%'+#searchText+'%'
end
FOR EXECUTE YOUR SP
exec [Your SP Name] 'Your Pram Value'
---Example---
exec SPEmployeeInformation 'your search text'
Happy Coding. :-)

SQL recursive udf always returns null

Create Table Employees
(
Employee varchar(10),
Manager varchar(10)
);
Insert into Employees
values
('Charlie',null),
('Peter','James'),
('Elai',null),
('Graham','Emanuel'),
('Amanda','Charlie'),
('Sen','Graham'),
('Emanuel',null),
('James','Amanda'),
('Elai',null),
('Victor','Elai');
Above "Employees" table contains employee and employee's manager name. When trying to retrieve comma separated hierarchy of a employee using below function, the result is always null.
for example :
employee 'Victor', hierarchy/result should be "Victor, Elai".
Could anyone point out what am I doing wrong in below UDF.
Create Function EmployeeHierarchy(#employeeName varchar(20))
Returns varchar(100)
AS
Begin
Declare #commaSeparatedHierarchy varchar(100);
Declare #manager varchar(20);
if(#employeeName is not null)
Begin
Select #manager=Manager from Employees where Employee=#employeeName;
Set #commaSeparatedHierarchy=dbo.EmployeeHierarchy(#manager)+','+#manager;
End
return #commaSeparatedHierarchy;
End;
First & foremost, you DO NOT want to create this as a scalar function. Their performance is horrible any udf you create, should be created as an inline table valued function. The following should do what you're looking for...
-- the test data...
USE tempdb;
GO
IF OBJECT_ID('tempdb.dbo.Employee', 'U') IS NOT NULL
DROP TABLE dbo.Employee;
CREATE TABLE dbo.Employee (
Employee varchar(10),
Manager varchar(10)
);
INSERT dbo.Employee (Employee, Manager) VALUES
('Charlie',null),
('Peter','James'),
('Elai',null),
('Graham','Emanuel'),
('Amanda','Charlie'),
('Sen','Graham'),
('Emanuel',null),
('James','Amanda'),
('Elai',null),
('Victor','Elai');
SELECT * FROM dbo.Employee e;
iTVF code...
CREATE FUNCTION dbo.EmployeeHierarchy
(
#employeeName varchar(20)
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
cte_Recur AS (
SELECT
CSH = CAST(CONCAT(e.Employee, ', ' + e.Manager) AS VARCHAR(1000)),
e.Manager,
NodeLevel = 1
FROM
dbo.Employee e
WHERE
e.Employee = #employeeName
UNION ALL
SELECT
CSH = CAST(CONCAT(r.CSH, ', ' + e.Manager) AS VARCHAR(1000)),
e.Manager,
NodeLevel = r.NodeLevel + 1
FROM
dbo.Employee e
JOIN cte_Recur r
ON e.Employee = r.Manager
WHERE
e.Manager IS NOT NULL
)
SELECT
commaSeparatedHierarchy = MAX(r.CSH)
FROM
cte_Recur r;
GO
Sample execution...
SELECT
eh.commaSeparatedHierarchy
FROM
dbo.EmployeeHierarchy('peter') eh;
... and the results...
commaSeparatedHierarchy
------------------------------
Peter, James, Amanda, Charlie

Stored Proc Query Timming Out in .net but not sql server

I have the following query and its timing out in .net but executing fine in sql server does .net not like temp tables or something ??? I run it in .net and i get a timeout error I dont understand what is going on at all.
SET DATEFORMAT dmy
declare #AbsenceReasonRestrictions varchar(500)
set #AbsenceReasonRestrictions ='1'
create table #absence
(
record_id INT,
emp_no int,
staff_no varchar(max),
emp_name varchar(max),
details text,
leave_reason int,
leave_reason_desc varchar(30),
current_status int,
date_added datetime,
dept int,
dept_desc varchar(100),
location int,
location_desc varchar(100),
division int,
division_desc varchar(100),
emptype int,
emptype_desc varchar(100),
contype int,
contype_desc varchar(100),
conclass int,
conclass_desc varchar(100),
line_manager int,
line_manager_name varchar(510)
)
INSERT INTO #absence (record_id,
emp_no,
staff_no,
emp_name,
details,
leave_reason,
leave_reason_desc,
current_status,
date_added,
dept,
dept_desc,
location,
location_desc,
division,
division_desc,
emptype,
emptype_desc,
contype,
contype_desc,
conclass,
conclass_desc,
line_manager,
line_manager_name)
select ua.record_id,
ua.emp_no,
e.staff_no,
rtrim(e.surname)+', '+rtrim(e.forename1),
ua.details,
ua.absence_reason,
ar.desc_,
ua.current_status,
ua.date_added,
c.dept,
rtrim(dept.desc_),
c.location,
rtrim(loc.desc_),
c.division,
rtrim(div.desc_),
c.emptype,
rtrim(emptype.desc_),
c.type,
rtrim(contype.desc_),
c.classification,
rtrim(conclass.desc_),
ua.manager_user_id,
(select rtrim(e.surname) + ', ' + rtrim(e.forename1) as emp_name from employee e
inner join userlist_mss um on e.emp_no = um.pams_id
where um.record_id = ua.manager_user_id)
from ess_absence_requests ua
inner join employee e on e.emp_no=ua.emp_no
inner join absreas ar on ar.code=ua.absence_reason
inner join contract c on ua.emp_no = c.emp_no
join dept on c.dept=dept.code
join location loc on c.location=loc.code
join division div on c.division=div.code
join emptype on c.emptype=emptype.code
join contype on c.type=contype.code
join conclass on c.classification=conclass.code
where e.emp_no like '%'
AND c.main_contract=1
AND ua.current_status in (1,2,3,4)
AND (dbo.fn_XmlElementDateValue(ua.details, 'start_date') >='1/10/2013')
AND (dbo.fn_XmlElementDateValue(ua.details, 'end_date') <='31/10/2013')
AND e.active_leaver like 'ACTIVE'
AND e.emp_no like '%'
and c.dept like '%'
and c.location like '%'
and c.division like '%'
and c.emptype like '%'
and c.classification like '%'
and c.type like '%'
and ua.emp_no in (select employee_id from userlist_mss_employee_access_rights where manager_id=2)
order by (dbo.fn_XmlElementDateValue(ua.details, 'start_date'))
if #AbsenceReasonRestrictions!=''
begin
set #AbsenceReasonRestrictions=','+#AbsenceReasonRestrictions+','
delete #absence where charindex(','+cast(leave_reason as varchar(10))+',', #AbsenceReasonRestrictions) = 0
end
select record_id,
emp_no,
staff_no,
emp_name,
details,
leave_reason,
leave_reason_desc,
current_status,
date_added,
dept_desc,
location_desc,
division_desc,
emptype_desc,
contype_desc,
conclass_desc,
line_manager,
line_manager_name from #absence
drop table #absence
select * from emp_anal
I think that the problem is that management studio has no timeout limit for your query, but when you run it within .net code you are limited connection timeout. Try to change the timeout directly in you connection string or in connection initialization place.
More info:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout(v=vs.110).aspx
Changing SqlConnection timeout
I guess it's because your direct sql call (using management studio?) uses a different query plan than your .net code ... and the plan .net uses seems to be no good ...
to resolve this try updating table statistics (update statistics ) for the tables used by your join and dbcc freeproccache to clear the cached query plans ...

Find manager in a comma-separated list

I have a Projects table with ID and Responsible manager. The Responsible manager columns has values as John,Jim for Project 1 and Jim,Julie for Project 2.
But if I pass Jim to my stored procedure I should get 2 projects (1,2). This returns no rows because the column is John,Jim but SQL Server is looking for ='Jim':
select distinct ID,Manager from Projects where Manager=#Manager
WHERE ',' + Manager + ',' LIKE '%,Jim,%'
Or I suppose to match your actual code:
WHERE ',' + Manager + ',' LIKE '%,' + #Manager + ',%'
Note that your design is extremely flawed. There is no reason you should be storing names in this table at all, never mind a comma-separated list of any data points. These facts are important on their own, so treat them that way!
CREATE TABLE dbo.Managers
(
ManagerID INT PRIMARY KEY,
Name NVARCHAR(64) NOT NULL UNIQUE, ...
);
CREATE TABLE dbo.Projects
(
ProjectID INT PRIMARY KEY,
Name NVARCHAR(64) NOT NULL UNIQUE, ...
);
CREATE TABLE dbo.ProjectManagers
(
ProjectID INT NOT NULL FOREIGN KEY REFERENCES dbo.Projects(ProjectID),
ManagerID INT NOT NULL FOREIGN KEY REFERENCES dbo.Managers(ManagerID)
);
Now to set up the sample data you mentioned:
INSERT dbo.Managers(ManagerID, Name)
VALUES(1,N'John'),(2,N'Jim'),(3,N'Julie');
INSERT dbo.Projects(ProjectID, Name)
VALUES(1,N'Project 1'),(2,N'Project 2');
INSERT dbo.ProjectManagers(ProjectID,ManagerID)
VALUES(1,1),(1,2),(2,2),(2,3);
Now to find all the projects Jim is managing:
DECLARE #Manager NVARCHAR(32) = N'Jim';
SELECT p.ProjectID, p.Name
FROM dbo.Projects AS p
INNER JOIN dbo.ProjectManagers AS pm
ON p.ProjectID = pm.ProjectID
INNER JOIN dbo.Managers AS m
ON pm.ManagerID = m.ManagerID
WHERE m.name = #Manager;
Or you can even manually short circuit a bit:
DECLARE #Manager NVARCHAR(32) = N'Jim';
DECLARE #ManagerID INT;
SELECT #ManagerID = ManagerID
FROM dbo.Managers
WHERE Name = #Manager;
SELECT p.ProjectID, p.Name
FROM dbo.Projects AS p
INNER JOIN dbo.ProjectManagers AS pm
ON p.ProjectID = pm.ProjectID
WHERE pm.ManagerID = #ManagerID;
Or even more:
DECLARE #Manager NVARCHAR(32) = N'Jim';
DECLARE #ManagerID INT;
SELECT #ManagerID = ManagerID
FROM dbo.Managers
WHERE Name = #Manager;
SELECT ProjectID, Name
FROM dbo.Projects AS p
WHERE EXISTS
(
SELECT 1
FROM dbo.ProjectManagers AS pm
WHERE pm.ProjectID = p.ProjectID
AND pm.ManagerID = #ManagerID
);
As an aside, I really, really, really hope the DISTINCT in your original query is unnecessary. Do you really have more than one project with the same name and ID?
In a WHERE clasue a = operator looks for an exact match. You can use a LIKE with wildcards for a partial match.
where Manager LIKE '%Jim%'
You may try the following:
SELECT DISTINCT
ID,
Manager
FROM
Projects
WHERE
(
(Manager LIKE #Manager + ',*') OR
(Manager LIKE '*,' + #Manager) OR
(Manager = #Manager)
)
That should cover both names and surnames, while still searching for literal values. Performance can be a problem however, depending on table
please tried with below query
select distinct ID,Manager from Projects where replace('#$#' + Manager + '#$#', ',', '#$#') like '%Jim%'

SP executing error

I am writing below SP.But when i try to run this query i am getting this error:
There is already an object named
'#myCourses1' in the database.
So this getting in two else loops. also
create proc [dbo].[GetOrdersByUserIDwithSubscription]
(
#UserID int
)
as
begin
declare #status varchar(500)
declare #substatus char(2)
select #substatus=Subscribe_status from tbl_user where userid=#userid
print #substatus
if #substatus='N'
BEGIN
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded into #myCourses1 from dbo.Tbl_CourseInformations a JOIN Tbl_Categories b ON a.AssignCategory = b.CategoryID
Join Tbl_Orders c ON c.UserID = #UserID and c.CourseID = a.CourseID and c.courseprice<>'subscriber'
Order By CategoryText, CourseTitle
END
else if #substatus=''
BEGIN
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded into #myCourses1 from dbo.Tbl_CourseInformations a JOIN Tbl_Categories b ON a.AssignCategory = b.CategoryID
Join Tbl_Orders c ON c.UserID = #UserID and c.CourseID = a.CourseID and c.courseprice<>'subscriber'
Order By CategoryText, CourseTitle
END
else if #substatus='Y'
BEGIN
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded into #myCourses1 from dbo.Tbl_CourseInformations a JOIN Tbl_Categories b ON a.AssignCategory = b.CategoryID
Join Tbl_Orders c ON c.UserID = #UserID and c.CourseID = a.CourseID
Order By CategoryText, CourseTitle
END
The SQL Parser is choking because you have used the same temp table name in different parts of the IF statement. The IF does not have scope like other programming languages.
If you do not need to reference the temp table outside of each of the IF blocks you can get around the problem by using a different table name in each part.
Have a look at my answer to a similar question.
Also, the monstrocity of a query you have could be reduced to this:
create proc [dbo].[GetOrdersByUserIDwithSubscription](
#UserID int
)
as
begin
declare #substatus char(2)
select #substatus = Subscribe_status
from tbl_user
where userid = #userid
select a.*, b.CategoryText,
Cast("" as Varchar(10)) as SectionsViewed,
PurchasedDate as dateadded
from dbo.Tbl_CourseInformations a
join Tbl_Categories b ON a.AssignCategory = b.CategoryID
join Tbl_Orders c ON c.UserID = #UserID
and c.CourseID = a.CourseID
and (#substatus = 'N' or c.courseprice <> 'subscriber')
order by CategoryText, CourseTitle
END
Explicitly create the temp table at the beginning of the proc.
CREATE TABLE #myCourses1 (
...
)
Then write your SELECT statements as:
INSERT INTO #myCourses1
select a.*, b.CategoryText, Cast('' as Varchar(10)) as SectionsViewed, PurchasedDate as dateadded
from dbo.Tbl_CourseInformations
...
You syntax is
SELECT [Column-List] INTO #TempTable FROM [Rest-of-Query]
When using this syntax, Sql Server attempts to create #TempTable on the fly based on your column list (source).
To get around this, either Drop #TempTable at the beginning of the stored procedure (if you do not need its data beyond the scope of the SP), or make it a permanent table.