Customer search stored procedure - sql

I am writing a customer search stored procedure which having three parameters firstname, lastname, fathers name all are varchar
I wrote like below :
CREATE PROCEDURE [dbo].[SearchCustomer]
(
#p_FirstName varchar = NULL
,#p_LastName varchar = NULL
,#p_FatherFirstName varchar = NULL
)
AS
BEGIN
SET NOCOUNT ON
SELECT [CustomerID]
,[CustomerTitle]
,[FirstName]
,[MiddleName]
,[LastName]
,[FatherFirstName]
,[EmailId]
FROM [Customer]
WHERE [FirstName] LIKE COALESCE(#p_FirstName,'%')
OR [LastName] LIKE COALESCE #p_LastName,'%')
OR [FatherFirstName] LIKE COALESCE(#p_FatherFirstName,'%')
END
I am using optional parameters because if there is no parameter value I need to get full listing without any criteria but when I give just first name I need only those rows which matching that criteria not the rest, but now its listing all
I guess the problem is somewhere near OR
Could you please help?
If i change OR to AND
now if i put first name as 'abc' and last name and father name black ...
i am getting all listing including 'abc' as first name..
i need only the row which having first name as 'abc' not the rest

This will filter rows depending on which parameters were submitted:
CREATE PROCEDURE [dbo].[SearchCustomer]
(
#p_FirstName varchar(50) = NULL
,#p_LastName varchar(50) = NULL
,#p_FatherFirstName varchar(50) = NULL
)
AS
BEGIN
SET NOCOUNT ON
SELECT [CustomerID]
,[CustomerTitle]
,[FirstName]
,[MiddleName]
,[LastName]
,[FatherFirstName]
,[EmailId]
FROM [Customer]
WHERE [FirstName] LIKE COALESCE(#p_FirstName + '%', FirstName)
AND [LastName] LIKE COALESCE (#p_LastName + '%', LastName)
AND [FatherFirstName] LIKE COALESCE(#p_FatherFirstName + '%', FatherFirstName)
END
GO

Use where clause like the example below .
WHERE (#p_FirstName='' or [FirstName] LIKE COALESCE(#p_FirstName,'%'))
OR (#p_LastName='' or [LastName] LIKE COALESCE #p_LastName,'%'))
OR (#p_FatherFirstName='' or [FatherFirstName] LIKE COALESCE(#p_FatherFirstName,'%'))
and set all your parameters '' if they are NULL by using following syntax.
SET #p_FirstName=ISNULL(#p_FirstName,'')

CREATE PROCEDURE [dbo].[SearchCustomer]
(
#p_FirstName varchar = NULL
,#p_LastName varchar = NULL
,#p_FatherFirstName varchar = NULL
)
AS
BEGIN
SET NOCOUNT ON
SELECT [CustomerID]
,[CustomerTitle]
,[FirstName]
,[MiddleName]
,[LastName]
,[FatherFirstName]
,[EmailId]
FROM [Customer]
WHERE [FirstName] LIKE COALESCE(#p_FirstName,'%')
OR (FirstName is NULL
AND [LastName] LIKE COALESCE(#p_LastName,'%')
AND [FatherFirstName] LIKE COALESCE(#p_FatherFirstName,'%'))
END

CREATE PROCEDURE [dbo].[SearchCustomer]
(
#p_FirstName varchar(50) = NULL
,#p_LastName varchar(50) = NULL
,#p_FatherFirstName varchar(50) = NULL
)
AS
BEGIN
SET NOCOUNT ON
SELECT [CustomerID]
,[CustomerTitle]
,[FirstName]
,[MiddleName]
,[LastName]
,[FatherFirstName]
,[EmailId]
FROM [Customer]
WHERE ([FirstName] = #p_FirstName OR #p_FirstName IS NULL)
AND ([LastName] = #p_LastName OR #p_LastName IS NULL)
AND ([FatherFirstName] = #p_FatherFirstName OR #p_FatherFirstName IS NULL)
END

Related

Table-Valued Function using IF statement in SQL Server

I have a Student table consists of following parameters
[ID] [nvarchar](50) NOT NULL,
[Firsname] [nvarchar](50) NOT NULL,
[Lastname] [nvarchar](50) NOT NULL,
[Melicode] [nchar](10) NOT NULL,
[City] [nvarchar](50) NOT NULL,
[Province] [nvarchar](50) NOT NULL,
[Active] [int] NULL
i want to write a Table-Valued Function named Show which has one parameter as number. the function will act as following
if #number = 1 , returns all columns from Student table
if #number = 2 , returns only City from Student
if #number = 3 , returns only Province from Student
i wrote the following T-SQL, but it only works for (if (#number = 1)). When the user enter #number as 2 or 3, the function does not work. Thank You
Create function Show(#number int)
RETURNS #result TABLE
(
[ID] [nvarchar](50) NOT NULL,
[Firsname] [nvarchar](50) NOT NULL,
[Lastname] [nvarchar](50) NOT NULL,
[Melicode] [nchar](10) NOT NULL,
[City] [nvarchar](50) NOT NULL,
[Province] [nvarchar](50) NOT NULL,
[Active] [int] NULL
)
AS
BEGIN
IF (#number = 1)
INSERT INTO #result SELECT * from Student
IF (#number = 2)
INSERT INTO #result (City) values ((SELECT City from Student))
IF (#number = 3)
INSERT INTO #result (Province) values ((SELECT Province from Student))
RETURN -- #Players (variable only required for Scalar functions)
END
go
select *from dbo.show(1)
This is not going to work:
INSERT INTO #result (City)
VALUES ((SELECT City from Student))
Either you have all the values as scalar SQL variables, or literals - then you can use
INSERT INTO #result (City)
VALUES ('New York')
INSERT INTO #result (City)
VALUES (#ChosenCity)
or you have a SELECT statement to fill the values - then you need this syntax:
INSERT INTO #result (City)
SELECT City
FROM Student
without the VALUES keyword. And as #GiorgiNakeuri correctly states - this will then fail because all your columns require a value (have the NOT NULL attribute), so this insert cannot succeed - you need to provide all NOT NULL values (or define a default value for each column)
CREATE FUNCTION dbo.Show
(
#number INT
)
RETURNS #result TABLE
(
ID NVARCHAR(50),
Firsname NVARCHAR(50),
Lastname NVARCHAR(50),
Melicode NCHAR(10),
City NVARCHAR(50),
Province NVARCHAR(50),
Active INT
)
AS
BEGIN
IF (#number = 1)
INSERT INTO #result
SELECT * FROM dbo.Student
IF (#number = 2)
INSERT INTO #result (City)
SELECT City FROM dbo.Student
IF (#number = 3)
INSERT INTO #result (Province)
SELECT Province FROM dbo.Student
RETURN
END
GO
SELECT * FROM dbo.Show(2)
the table returned is dictated by how the result table was declared. the query below works (in a sense) but the results include all the columns with NULLs for those columns not targeted by the #number parameter:
CREATE TABLE dbo.z_Show (str1 VARCHAR(10), str2 VARCHAR(10), str3 VARCHAR(10))
INSERT z_show
SELECT 1, 1, 1 UNION ALL
SELECT 2, 2, 2 UNION ALL
SELECT 3, 3, 3
CREATE FUNCTION dbo.Show(#number int)
RETURNS #result TABLE
(
--[ID] [nvarchar](50) NOT NULL,
--[Firsname] [nvarchar](50) NOT NULL,
--[Lastname] [nvarchar](50) NOT NULL,
--[Melicode] [nchar](10) NOT NULL,
--[City] [nvarchar](50) NOT NULL,
--[Province] [nvarchar](50) NOT NULL,
--[Active] [int] NULL
str1 VARCHAR(10), str2 VARCHAR(10), str3 VARCHAR(10)
)
AS
BEGIN
--for debugging|start
--DECLARE #number INT = 3
--DECLARE #result TABLE (str1 VARCHAR(10), str2 VARCHAR(10), str3 VARCHAR(10))
--for debugging|end
IF (#number = 1)
BEGIN
--PRINT ('IF (#number = 1)')
INSERT INTO #result SELECT * from dbo.z_Show
END
IF (#number = 2)
BEGIN
--PRINT ('IF (#number = 2)')
INSERT INTO #result (str2) SELECT str2 from dbo.z_Show
END
IF (#number = 3)
BEGIN
--PRINT ('IF (#number = 3)')
INSERT INTO #result (str3) SELECT str3 from dbo.z_Show
END
RETURN -- #Players (variable only required for Scalar functions)
END
SELECT 'number 1 was passed', *
FROM dbo.show(1)
SELECT 'number 2 was passed', *
FROM dbo.show(2)
SELECT 'number 3 was passed', *
FROM dbo.show(3)
You mentioned #result has all NOT NULL columns. If you want to insert only city into that #result, it will take remaining columns as Null so that's why an error happened. You don't mention that #result columns are NOT NULL columns and one more is. Remove VALUES keyword from the INSERT statement because it is inserting with a Select statement
The insert statements for cases 2 and 3 are incorrect. No need for VALUES keyword when inserting values coming from a select statement.

How to return multiple varchar from a stored procedure where condition is met

Hi I have created a Table in which I am storing first name, last name and email ID of some persons.
The table is as follows:
create table frnds
(
id int Primary Key,
firstName varchar (20) not null,
lastName varchar (20) not null,
emailID varchar (30)not null
)
I have to write a Stored Procedure to return the "first name" values from the table wherever there is a match with the input "last name" value.
I have some of the names with common last names. So I want to have all the first names as the output of the Stored Procedure.
I am using the following code to do that but have been able to get only one matching first name as output.
Create Procedure GetFirstName
(
#lastName varchar(20),
#firstName varchar(20) OUT
)
AS
Begin
Select #firstName = firstName from frnds where lastName = #lastName
End
Also this is how I am displaying the result:
declare #LastName varchar (20)
Exec GetFirstName Daniels, #LastName output
select #LastName
I know that this is because I have the output parameter such that it can hold only one matching first name. Since I am new to SQL, I am not able to figure out how to achieve this. Please help with any suggestion or some link which can guide me in the right direction.
Thanks!!!
You can use temporary table do store the varchars.
First create your procedure like this:
Create table #temp
(
fisrtName varchar(20) not null
)
go
Create Procedure GetFirstName
(
#lastName varchar(20)
-- , #firstName varchar(20) OUT with my solution you don't need it
)
AS
Begin
insert into #temp
Select firstName from frnds where lastName = #lastName
End
go
drop table #temp
Then you can use it as below
Create table #temp
(
fisrtName varchar(20) not null
)
exec GetFirstName 'Daniels'
select * from #temp
Try this
Create Procedure GetFirstName
(
#lastName varchar(20),
#firstName varchar(20) OUT
)
AS
Begin
Select firstName from frnds where lastName = #lastName
End
Create table #lastname(lastname varchar (20))
Insert into #lastname
Exec GetFirstName 'Daniels'
select * from #lastname
CREATE FUNCTION [myschema].[returnLastNames]
(
#lastName varchar(20),
)
RETURNS TABLE
AS
RETURN SELECT firstName from frnds where lastName = #lastName;
A function might be better here maybe?
Use it like f.ex.:
SELECT * FROM myschema.returnLastNames('Stevensson');
IF OBJECT_ID('usp_GetFirstName', 'P') IS NOT NULL
DROP PROCEDURE usp_GetFirstName;
GO
Create Procedure usp_GetFirstName
(
#lastName varchar(20),
#firstName varchar(20) OUTPUT
)
AS
Begin
SET NOCOUNT ON;
Select #firstName = firstName from frnds where lastName = #lastName;
RETURN
End
GO
DECLARE #Person varchar(20);
EXECUTE usp_GetFirstName
N'Daniels',#lastName = #Person OUTPUT;
PRINT 'LAST NAme IS' + #Person;
GO

How to view rows inserted in StoredProcedure's temporary table during SSIS package execution

ALTER PROC [dbo].[StoredProcedure1] (#XMLRows XML)
AS
BEGIN
SET NOCOUNT ON
DECLARE #myTable TABLE
(
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[Gender] [char](1) NULL
)
Insert into #myTable
(
FirstName ,
LastName ,
Gender
)
SELECT distinct
FirstName
,LastName
,Coalesce(Gender,'') Gender
FROM
(
SELECT
items.value (N'FirstName[1]', 'nvarchar(50)') AS [FirstName]
,items.value (N'LastName[1]', 'nvarchar(50)') AS [LastName]
,items.value (N'Gender[1]', 'char(1)') AS [Gender]
FROM #ExportData a
CROSS APPLY XML_File.nodes('MyNode/Employee') AS NodeTable(Specs)
OUTER APPLY XML_File.nodes('MyNode/Employee/StaffList') AS NodeTable1(items)
OUTER APPLY XML_File.nodes('MyNode/Employee/OtherDetails') AS NodeTable2(items2)
OUTER APPLY XML_File.nodes('MyNode/Employee/MoreDetailsHere') AS NodeTable3(items3)
OUTER APPLY XML_File.nodes('MyNode/EvenMoreDetails') AS NodeTable4(items4)
)myTable
END
I have the above stored StoredProcedure which i am calling from an SSIS package. Is there any way i can view the rows inserted in the temporary table #myTable when the package is executed. I am troubleshooting a bug and i want to see exactly what is in #myTable when my package is executed.
Seperate to your stored procedure. Create another "real" table in your database.
CREATE TABLE MyTableLog
(
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[Gender] [char](1) NULL
)
Then during your stored procedure execution, truncate the real table, and repopulate it with the contents generated during your sproc
ALTER PROC [dbo].[StoredProcedure1] (#XMLRows XML)
AS
BEGIN
SET NOCOUNT ON
DECLARE #myTable TABLE (...)
Insert into #myTable (...)
SELECT distinct ...
TRUNCATE TABLE MyTableLog
INSERT INTO MyTableLog (FirstName, LastName, Gender)
SELECT FirstName, LastName, Gender FROM #myTable
END
Once your SPROC has finished executing via the SSIS Package, you can simply query your log table from any query window.
SELECT FirstName, LastName, Gender FROM MyTableLog

Checking for table columns before adding them in SQL Server

I need to script out a table modification at work. Rather than do a simple "if exists then drop and create", they want it to check for the new columns I'm adding, and only then alter the table with them if they don't exist.
Could someone help me with the script? Assume a simple table that looks like this currently:
CREATE TABLE myTable (
[ID] [int] NOT NULL,
[FirstName] [varchar] (20) NOT NULL,
[LastName] [varchar] (20) NOT NULL
)
.. I'd like to add an Address field, varchar(50) let's say, but only if it doesn't already exist in the schema.
IF NOT EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'myTable' AND COLUMN_NAME = 'Address')
BEGIN
ALTER TABLE [dbo].[myTable] ADD
[Address] varchar(50) NOT NULL
END
Try this
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[myTable ]') AND type in (N'U'))
BEGIN
DROP TABLE [dbo].[myTable ]
END
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE myTable (
[ID] [int] NOT NULL,
[FirstName] [varchar] (20) NOT NULL,
[LastName] [varchar] (20) NOT NULL,
[Address] [varchar] (50) NOT NULL
)
OR
if not exists(select * from sys.columns
where Name = N'Address' and Object_ID = Object_ID(N'myTable'))
begin
alter table myTable
add Address varchar(50) NOT NULL
end
GO
Try this:
Here using it you can make check for multiple columns and get you table altered...
DECLARE #query VARCHAR(MAX)
IF EXISTS(SELECT * FROM sys.columns
WHERE Name = N'Address' AND OBJECT_ID = OBJECT_ID(N'<TableName>'))
BEGIN
SET
#query = 'ALTER TABLE <TableName> ADD Address varchar(50) GO'
END
--You can give multiple If conditions, example:
--IF EXISTS(SELECT * FROM sys.columns
--WHERE Name = N'<SomeOtherColumn>' AND OBJECT_ID = OBJECT_ID(N'<TableName>'))
--BEGIN
--SET
--#query = #query + 'ALTER TABLE <TableName> ADD <SomeOtherColumn> varchar(50) GO'
--END
EXEC sp_Executesql #query
IF 'col_name'
NOT IN
SELECT Name
FROM table_name.columns
ALTER TABLE table_name
ADD 'col_name' VARCHAR(65) NOT NULL
something like this?
EDIT: my friend believes this is much better
IF NOT EXISTS
(SELECT Name
FROM table_name.columns
Where Name='target_column_name')
ALTER TABLE table_name
ADD 'target_column_name' VARCHAR(65) NOTNULL

A simple query in stored procedure

Need to make a stored procedure that will do a simple search on a table, plus have 3 parameters, the first two are a date range, the third is if different from NULL will be included in the WHERE, if equal to NULL then not seek that value, as I can do this search?
Where #parameter1 = ColA
AND #parameter2 = ColB
and ISNULL(#parameter3, ColC) = ColC
try this..
Create Prucedure test
#p1 int,#p2 int,#p3 nvarchar(50)
As
Begin
If #p3 is null
Select * from table where field1=#p1 and field2=#p2
Else
Select * from table where field1=#p1 and field2=#p2 and field3=#p3
End
Sorry for improper formatting this is because i am sending the answer from a cell phone
WHERE #parameter IS NULL or field = #parameter
Yes! you can do that by passing the three variables to the host program and write a customized CURSOR SELECT using them. Then open the cursor and throw the resultset. Your search results are now ready to use. If needed syntactical help, revert with the host language and specifications you are using. Do post the challenges and solution you got for the same, may help others.
Try the following. Note that if Column3 could be null then you need to use the isnull() function on the column name as well as you can't compare null values. So if the data type of Column3 is int then you could use: and isnull(Column3, 0) = isnull(#param3, isnull(Column3, 0)).
create procedure Test
#param1 varchar(50),
#param2 varchar(50),
#param3 varchar(50) = null
as
begin
select *
from Table1
where Column1 = #param1
and Column2 = #param2
and Column3 = isnull(#param3, Column3)
end
The general form of what you are attempting to perform is a dynamic query. See the solution in this problem update statement not executing
I am using the adventure works database.
CREATE PROCEDURE upContactDetails
#FirstName [nvarchar](50),
#LastName [nvarchar](50),
#MiddleName [nvarchar](50)
AS
BEGIN
SET NOCOUNT ON;
SELECT Title
, FirstName
, MiddleName
, LastName
, EmailAddress
FROM Person.Contact
WHERE (#MiddleName IS NULL or MiddleName = #MiddleName)
AND FirstName = #FirstName
AND LastName = #LastName
END
GO
Imagine that You're having a transaction table where you store transaction Number And Transaction Date as shown Below.
CREATE TABLE [dbo].[TrnMast](
[TrnNo] [numeric](10, 0) NOT NULL,
[AcYear] [int] NOT NULL,
[Comp_Code] [varchar](5) NOT NULL,
[InvNo] [varchar](20) NULL,
[TrnDate] [datetime] NULL,
[P_Code] [varchar](5) NULL,
[Amount] [money] NULL,
[Remark] [varchar](50) NULL
CONSTRAINT [PK_TrnMast_1] PRIMARY KEY CLUSTERED
(
[TrnNo] ASC,
[Comp_Code] ASC,
[AcYear] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Now Look at stored procedure with 3 parameters having two date range paramaters and TrnNo Below.
CREATE PROCEDURE [dbo].[SP_TrnMast]
#FTrnDate SmallDateTime = Null,
#TTrnDate SmallDateTime = Null,
#AcYear Int
AS
Begin
Select * From TrnMast
Where (#FTrnDate Is Null Or TrnMast.TrnDate >= #FTrnDate)
And (#TTrnDate Is Null Or TrnMast.TrnDate <= #TTrnDate)
And TrnMast.AcYear = #AcYear
End