how to execute stored procedure in sql using join - sql

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. :-)

Related

How do a Skip a Row With SQL Cursor without a Temp Table

I have a large table in SQL with the following columns:
CompanyId(int)
Email(Varchar 255)
First_Name(Varchar 50)
Last_Name(Varchar 50)
1
jim_halpert#dundermifflin.com
Jim
Halpert
2
bvance#vancerefridgerations.com
Bob
Vance
1
michael_scott#dundermifflin.com
Michael
Scott
CompanyId can repeat several times as the companies are attached to various emails.
My employer wants me to find Company emails that belong to a specific type. After several IF statements, the end result would print a message like:
"CompanyId" has firstName_lastName#companyName.domain type email
"CompanyId" has firstInitial_lastName#companyName.domain type email
My employers told me to use Cursor to find my solution, but once I start my cursor I need to check the CompanyId to see if that id has already been looped and a type found. If the CompanyId has already gone through the cycle, I want to skip it.
This is my code thus far
DECLARE #CoId INT
,#Email VARCHAR(255)
,#FName varchar(50)
,#LName varchar(50)
Declare #condition bit = 1
Declare CoCursor CURSOR
For SELECT E.CompanyID, E.Email, P.First_Name, P.Last_Name
From Table_Email as E
Left Join Table_People as P
ON E.EmployeeID = P.EmployeeID
Order by CompanyID, Email
-- Loop through the rows with Cursors for CompanyId and Email
OPEN CoCursor
Fetch NEXT FROM CoCursor
INTO #CoId, #Email, #FName, #LName
While ##FETCH_STATUS = 0
BEGIN
-- Check to see if CompanyId has been logged before, if not, proceed
-- Check to see if email matches criteria
IF #Email LIKE #FName + '[_]' + #LName + '#%'
BEGIN
-- If yes, check next email where CompanyIds match
;WITH EmailTable(CompanyID, Email, First_Name, Last_Name) AS (
SELECT E.CompanyID, E.Email, P.First_Name, P.Last_Name
From Table_Emails as E
Left Table_People as P
ON E.EmployeeID = P.EmployeeID
Where E.CompanyID = #CoId
And E.Email LIKE P.First_Name + '[_]' + P.Last_Name + '#%')
Select TOP(2) #condition = 0
FROM EmailTable
Having COUNT(*) > 1
-- If email matches previous email, log Company Id with the email type
IF #condition = 0
PRINT CONVERT(VARCHAR(50), #CoId) + ' has email like firstName_lastName#CompanyAddress.domain'
-- If not, go to next Email check
END
IF #Email LIKE LEFT(#FName,1) + #LName + '#%'
-- If yes, check next email where CompanyIds match
-- If email matches previous email, log Company Id with the email type
-- If it has been logged move onto next record.
Fetch NEXT FROM CoCursor
INTO #CoId, #Email, #FName, #LName
-- Once the result is logged go to next row
END
CLOSE CoCursor
DEALLOCATE CoCursor
One solution I saw used a temp table to log ids that have been used before, but my employer doesn't want me using temp tables.
How Can I Skip a row(an iteration) in MSSQL Cursor based on some condition?
Thank you!
Cursors are slow and inefficient, and are rarely needed.
This doesn't need a cursor at all. A simple filtered join with a group by will suffice
SELECT
CONCAT(e.CompanyID), ' has email like firstName_lastName#CompanyAddress.domain')
FROM Table_Email e
JOIN Table_People p ON p.EmployeeID = e.EmployeeID
WHERE e.Email LIKE p.First_Name + '[_]' + p.Last_Name + '#%'
GROUP BY
e.CompanyID
ORDER BY
e.CompanyID;
Apparently, for some very strange reason, your employers have mandated a cursor, and I'm sure you will tell them all the reasons why not to use them. But here you go anyway:
Your original code is still very convoluted, and you can simplifiy it by using the code above as the SELECT for the cursor.
Note the use of a local variable for the cursor, this means you don't have to deallocate it
DECLARE #CompanyID int;
DECLARE #crsr CURSOR;
SET #crsr = CURSOR FAST_FORWARD FOR
SELECT
e.CompanyID
FROM Table_Email e
JOIN Table_People p ON p.EmployeeID = e.EmployeeID
WHERE e.Email LIKE p.First_Name + '[_]' + p.Last_Name + '#%'
GROUP BY
e.CompanyID
ORDER BY
e.CompanyID;
OPEN #crsr;
FETCH NEXT FROM #crsr
INTO #CompanyID;
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT CONCAT(e.CompanyID), ' has email like firstName_lastName#CompanyAddress.domain');
FETCH NEXT FROM #crsr
INTO #CompanyID;
END;
CLOSE #crsr;
I do not like cursors too much, so I am going to propose another possible solution (I think it is a better one, although your employers want a cursor for some strange reason).
Your sample data:
create table Table_Email (
CompanyID int,
EmployeeID int,
Email varchar(255)
)
create table Table_People (
CompanyID int,
EmployeeID int,
First_Name varchar(50),
Last_Name varchar(50),
)
insert into Table_Email values (1, 1, 'jim_halpert#dundermifflin.com')
insert into Table_Email values (2, 2, 'bvance#vancerefridgerations.com')
insert into Table_Email values (1, 3, 'michael_scott#dundermifflin.com')
insert into Table_People values (1, 1, 'Jim', 'Halpert')
insert into Table_People values (2, 2, 'Bob', 'Vance')
insert into Table_People values (1, 3, 'Michael', 'Scott')
My proposed query:
SELECT CONVERT(VARCHAR(50), CompanyID) + ' has email like firstName_lastName#CompanyAddress.domain' FROM
(
SELECT E.CompanyID, E.Email, P.First_Name, P.Last_Name
From Table_Email as E Left Join Table_People as P
ON E.EmployeeID = P.EmployeeID
WHERE Email LIKE P.First_Name + '[_]' + P.Last_Name + '#%'
) AS a
group by CompanyID
order by CompanyID
It returns:
1 has email like firstName_lastName#CompanyAddress.domain
SQL Fiddle: http://sqlfiddle.com/#!18/4c30e8/1
Make CompanyId Distinct in the the Cursor
Declare CoCursor CURSOR
For Select CompanyID,
Email,
First_Name,
Last_Name
FROM (SELECT E.CompanyID,
E.Email,
P.First_Name,
P.Last_Name,
ROW_NUMBER() OVER(PARTITION BY E.CompanyID ORDER BY E.Email ASC) as RN
From Table_Emails as E
Left Table_People as P
ON E.EmployeeID = P.EmployeeID) as T
Where RN = 1
Order by CompanyID

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

SQL Query To Get Structured Result

Sir, below is my SQL query, followed with two images of Query Result & Required Output.
As you can see on Result image that I have got this output from executing the following query.
There is second image of Required Output. I would need to display the output in that format. As First Department name should be at top & below Project details correspond to that department. The same cycle should get repeated for each and every department.
How should I achieve this ?
SQL Code:
DECLARE #ColName varchar(20)=null,
#Query varchar(MAX)=null,
#DepartmentName varchar(50)=null,
#deptt_code varchar(4)=null,
#DistrictId varchar(4)='0001',
#Deptt_Id char(4)=null,
#stYear varchar(4)=null,
#cYear varchar(4)=null,
#yr varchar(9)='2017-2018',
#tno int
BEGIN
set #stYear = SUBSTRING(#yr,0,5);
set #cYear = SUBSTRING(#yr,6,4);
--CREATE DYNAMIC TABLE WITH COLs
DECLARE #DepartmentTable table
(
department_name varchar(50),
department_code varchar(4)
);
DECLARE #ProjectTable table
(
project_name varchar(130),
project_code varchar(15),
department_code varchar(4),
department_name varchar(50),
district_code varchar(4),
district_name varchar(30),
tehsil_code varchar(6),
tehsil_name varchar(30),
service_code varchar(3),
[service_name] varchar(30),
sector_code varchar(3),
sector_name varchar(30),
project_start_year varchar(8),
project_compl_year varchar(8),
financial_year varchar(9)
);
--Insert into Department Table
INSERT INTO #DepartmentTable (department_code, department_name)
select deptt_code,deptt_name+'('+ RTRIM(LTRIM(deptt_short))+')' as dept_name from m_Department
where deptt_code in (select distinct department_code from t_Project_Details where district_id=#DistrictId
and financial_year=#yr);
--Insert into Project Table With Corresponding Department Name & Code
insert into #ProjectTable (
department_code,
project_code,
project_name,
department_name,
district_code,
district_name,
tehsil_code,
tehsil_name,
service_code,
[service_name],
sector_code,
sector_name,
project_start_year,
project_compl_year,
financial_year
)
SELECT pd.department_code,
pd.project_Code,
pd.project_name,
d.deptt_name,
pd.district_id,
di.district_name,
pd.tehsil_id,
t.tehsil_name,
pd.service_code,
s.[service_name],
pd.sector_code,
se.sector_name,
CONVERT(varchar,YEAR(pd.project_initiation_fin_from_yr)) + ' ' + CONVERT(varchar(3),pd.project_initiation_fin_from_yr,100) as project_start_year,
CONVERT(varchar,YEAR(pd.project_initiation_fin_to_yr)) + ' ' + CONVERT(varchar(3),pd.project_initiation_fin_to_yr,100) as project_compl_year,
pd.financial_year
FROM t_Project_Details pd
INNER JOIN m_Department d
ON d.deptt_code=pd.department_code
INNER JOIN m_Service s
ON s.service_code = pd.service_code
INNER JOIN m_Sector se
ON se.sector_code=pd.sector_code
INNER JOIN m_District di
ON di.district_code=pd.district_id
INNER JOIN m_Tehsil t
ON t.tehsil_code = pd.tehsil_id
WHERE
district_id=#DistrictId and
financial_year=#yr;
--select all from Department Table;
select * from #ProjectTable;
END
Query Result Image: https://drive.google.com/open?id=0Bxn7UXgmstmRaS1qX21kbjlwZzg
Required Output Image: https://drive.google.com/open?id=0Bxn7UXgmstmRekJkUWhBcmNCbk0
Your required output is a presentation layer issue; SQL can return your results but cannot make one row contain one thing and following rows contain many different things in a different format.
A SQL resultset will contain the same number of columns in all rows each with the same datatype.
Use something like SSRS to acheive your desire output.

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 ...

How can i optimize this stored procedure Without Join

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.