Stored procedure is not accepting null - sql

I am executing this stored procedure and it works fine, but when I am calling from the frontend side, it returns no rows.
ALTER PROCEDURE [dbo].[USP_GetRequest_DataListForViewPrint]
#RequestNo VARCHAR(50) = null,
#FromDate varchar(50) = null,
#ToDate varchar(50) = null
AS
BEGIN
DECLARE #SQLStr varchar(8000), #WHERECRI VARCHAR(1000) = NULL
IF (#RequestNo IS NOT NULL)
BEGIN
SET #WHERECRI = 'WHERE RequestNo='+ CHAR(39)+#RequestNo+ CHAR(39) ;
END
ELSE
BEGIN
SET #WHERECRI = ' WHERE RequestDate BETWEEN ' + CHAR(39) + CONVERT(varchar(10), CONVERT(datetime, #FromDate, 105), 102) + CHAR(39) + 'AND' + CHAR(39) + CONVERT(varchar(10), CONVERT(datetime, #ToDate, 105), 102) + CHAR(39);
END
SET #SQLStr = 'SELECT Id, RequestStatus, RequestDate, RequestNo FROM CYGNUX_Request_Header ' + #WHERECRI;
PRINT #SQLStr;
EXEC(#SQLStr);
END
In the frontend it take parameter this way and this is does not return any data:
EXEC USP_GetRequest_DataListForViewPrint '', '08-06-2020 00:00:00','16-06-2020 00:00:00'
But if I execute this in SQL Server this way it is returning data. I don't know what's wrong in my frontend
EXEC USP_GetRequest_DataListForViewPrint null, '08-06-2020 00:00:00','16-06-2020 00:00:00'
Please help me - how can I solve this?

In the frontend you are not passing NULL but an empty string, therefor your SP is executing the Select with a WHERE on RequestNo equal to an empty string which probably doesn't return any record.

Related

Select from #localvariable

I have a table of my server path, and I have a stored procedure where I need to call my server path base on the platform. I don't know why it's not working. Below is what I have so far.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [POLSAPSU].[SelectOrdersPOLDate] (#FROM DATETIME, #TO DATETIME)
AS
DECLARE #serverpath varchar(255)
DECLARE #query varchar(max)
BEGIN
SET #serverpath = (SELECT [path] from [param] where [platform] = 'POL')
SET #query = '
select 'POL' + '0'+ordh_sysrefno as ZINDEX,ordh_conttp AS POL_ORD_PKG_TYPE, ordh_pckgrefno AS POL_PKG_REFNO, '''' AS POL_PKG_PRODN, ''1101'' AS SALES_ORG, ''10'' AS DISTR_CHAN, ''11'' AS DIVISION, '''' AS POL_RTV_L_N, '''' AS CT_VALID_F, '''' AS CT_VALID_T, ordh_docno AS PURCH_NO_C
from ' + #serverpath +'.ord_hdr A''
where cast(ordh_createdate as date) BETWEEN #FROM AND #TO
and Exists(select * from ' + #serverpath +'.ord_dtl B where B.ordd_sysrefno = ordh_sysrefno)
union
select ''POL''+pkgh_production+ pkgh_refno, pkgh_type, '''', pkgh_production, ''1101'', ''10'', ''11'', '',convert(varchar(8),pkgh_effst,112), convert(varchar(8),pkgh_effend,112), pkgh_docno
from ' + #serverpath + '.pckg_hdr where cast(pkgh_createdate as date) BETWEEN #FROM AND #TO'
EXEC (#query)
END
I'm getting this error:
Incorrect syntax near '
where cast(ordh_createdate as date) BETWEEN #FROM AND #TO
and Exists(select * from POLTESTSERVER.POL.sysadm.ord_dtl B where '.
I am also considering this kind of approach
Select * from (select serverpath where platform = pol)
but I need to add the table name after the select statement in from clause and I don't have idea how. I am using SQL Server 2019.
Thank you.
I found multiple issues here.
Date parameters inside the sql query string are not properly escaped.
Use concat() function instead of adding those constants and columns
Columns with empty values are not property escaped.
Try below updated script.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [POLSAPSU].[SelectOrdersPOLDate] (#FROM DATETIME, #TO DATETIME)
AS
DECLARE #serverpath varchar(255)
DECLARE #query varchar(max)
BEGIN
SET #serverpath = (SELECT [path] from [param] where [platform] = 'POL')
SET #query = '
select concat(''POL'',''0'', ordh_sysrefno) as ZINDEX
,ordh_conttp AS POL_ORD_PKG_TYPE, ordh_pckgrefno AS POL_PKG_REFNO
, '''' AS POL_PKG_PRODN, ''1101'' AS SALES_ORG, ''10'' AS DISTR_CHAN, ''11'' AS DIVISION
, '''' AS POL_RTV_L_N, '''' AS CT_VALID_F, '''' AS CT_VALID_T, ordh_docno AS PURCH_NO_C
from ' + #serverpath +'.ord_hdr A
where cast(ordh_createdate as date) BETWEEN '''+ cast(#FROM as varchar(30)) +''' AND '''+ cast(#TO as varchar(30)) +'''
and Exists(select * from ' + #serverpath +'.ord_dtl B where B.ordd_sysrefno = ordh_sysrefno)
union
select concat(''POL'', pkgh_production, pkgh_refno), pkgh_type, '''', pkgh_production, ''1101'', ''10'', ''11'', '''', convert(varchar(8),pkgh_effst,112), convert(varchar(8),pkgh_effend,112), pkgh_docno
from ' + #serverpath +'.pckg_hdr where cast(pkgh_createdate as date) BETWEEN '''+ cast(#FROM as varchar(30)) +''' AND '''+ cast(#TO as varchar(30)) +''''
EXEC (#query)
END

Facing stored procedure related issue like Conversion failed when converting date and/or time from character string

Here is my stored procedure and in Status='2' I get an error for conversion and here I am trying to find last week data including today. I will be grateful if anybody can help me with this.
Here is screenshot of error I get :
Error facing
Code:
ALTER PROCEDURE [dbo].[USP_GetRequest_DataListForViewPrint]
#RequestNo VARCHAR(50),
#FromDate varchar(50),
#ToDate varchar(50),
#Status varchar(20)
AS
BEGIN
DECLARE #SQLStr varchar(8000)
DECLARE #CurrentDate Varchar(100) =GETDATE()
IF (#RequestNo IS NOT NULL)
BEGIN
BEGIN
SET #SQLStr = 'SELECT Id,RequestStatus, RequestNo,RequestDate From CYGNUX_Request_Header WHERE RequestNo='+''''+#RequestNo+'''';
END
END
ELSE
IF #Status = '1'
BEGIN
SET #SQLStr = 'select Id,RequestStatus,RequestDate,RequestNo from CYGNUX_Request_Header where RequestDate between '+CHAR(39)+ convert(varchar(50) , #FromDate) +CHAR(39)+ ' AND '+CHAR(39)+ convert(varchar(50), #ToDate) +CHAR(39);
END
IF #Status ='2'
BEGIN
SET #SQLStr = 'select Id,RequestStatus, RequestNo, RequestDate from CYGNUX_Request_Header where RequestDate>='+(DATEADD(day,-11117,GETDATE()));
END
IF #Status ='3'
BEGIN
SET #SQLStr = 'select Id,RequestStatus,RequestNo, RequestDate As Today from CYGNUX_Request_Header Where RequestDate='+CHAR(39)+ convert(varchar(50) , #CurrentDate) +CHAR(39) ;
END
IF #Status ='4'
BEGIN
SET #SQLStr = 'select Id,RequestStatus, RequestNo,RequestDate from CYGNUX_Request_Header WHERE RequestDate<=' +CHAR(39)+ convert(varchar(50) , #CurrentDate) +CHAR(39);
END
PRINT #SQLStr;
EXEC(#SQLStr);
END
Below you can find the right T-SQL
IF #Status ='2'
BEGIN
SET #SQLStr = '
SELECT Id,RequestStatus, RequestNo, RequestDate
FROM CYGNUX_Request_Header
WHERE RequestDate>='+CAST(DATEADD(day,-11117,GETDATE()) AS varchar(50))
END
In the if #status = 2 condition, the expression (DATEADD(day,-11117,GETDATE())) returns a value of type datetime. You are trying to concatenate that onto the end of a string using the + operator. You can't do that:
select 'my character value' + getdate() -- << fails
select 'my character value' + convert(varchar, getdate(), 121) -- OK
This will fix your specific error, but your code has a lot of room for improvement in other areas as well. If you have a colleague with more SQL experience, see if they can give you some pointers.

getting error while converting to date time in stored procedure

I am getting error like:
Msg 241, Level 16, State 1, Procedure spQueryMgt, Line 106 [Batch
Start Line 13] Conversion failed when converting date and/or time
from character string.
ALTER PROCEDURE [dbo].[spQueryMgt]
#Mode varchar(50)='',
#Query_Form varchar(20)='',
#Patient_ID bigint=0,
#Verified_By bigint = 0,
#Verified_Date datetime=''
AS
BEGIN
IF(#mode='Post_Query')
BEGIN
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'Update '+ CONVERT(varchar(12), #Query_Form) +' Set
Verified_By='+CONVERT(VARCHAR(12), #Verified_By)+',
Verified_Date='''+CONVERT(datetime, #Verified_Date,20)+'''
where Patient_ID = '+CONVERT(varchar(12), #Patient_ID)
EXEC sp_executeSQL #sql;
END
END
Change your query to -
SET #sql = N'Update '+ CONVERT(varchar(12), #Query_Form) +' Set
Verified_By='+CONVERT(VARCHAR(12), #Verified_By)+',
Verified_Date='''+CONVERT(VARCHAR(20), #Verified_Date,20)+'''
where Patient_ID = '+CONVERT(varchar(12), #Patient_ID)
There is issue with your convert function. You are converting #Verified_Date to datetime and concatenating datetime to varchar string.
The problem was that you where converting datetime back into datetime, and then tried to concatinate which gives you that exception.
But also, by initializing parameters to '' and 0 you are filling your database with unnesesary values like '' for varchars and 1900-01-01 for datetime columns and even worse 0 in integer columns.
Is that what you really want ? I doubt it.
It will be impossible to determine if a field was intentionaly set to this value or was left empty and get you into troubles later.
You can do your procedure like this to get NULL values in empty parameters
ALTER PROCEDURE [dbo].[spQueryMgt] (
#Mode varchar(50) = NULL,
#Query_Form varchar(20) = NULL,
#Patient_ID bigint = NULL,
#Verified_By bigint = NULL,
#Verified_Date datetime = NULL
)
AS
BEGIN
SET NOCOUNT ON;
IF #mode ='Post_Query'
BEGIN
DECLARE #sql NVARCHAR(MAX);
if (#Query_Form is not null) and (#Patient_ID is not null) -- nu use in updating when no table or id is given
begin
SET #sql = N' Update ' + CONVERT(varchar(12), #Query_Form) +
' Set Verified_By = ' + isnull(CONVERT(VARCHAR(12), #Verified_By), 'null') + ',' +
' Verified_Date = ' + case when #Verified_Date is null then 'null' else '''' + CONVERT(varchar(20), #Verified_Date, 20) + '''' end +
' where Patient_ID = ' + isnull(CONVERT(varchar(12), #Patient_ID), 'null')
EXEC sp_executeSQL #sql;
end
END
END
EDIT
As mentioned in the comments you should also take care of sql injection, and that makes your procedure safer, but also even easier
create PROCEDURE [dbo].[spQueryMgt] (
#Mode varchar(50) = NULL,
#Query_Form varchar(20) = NULL,
#Patient_ID bigint = NULL,
#Verified_By bigint = NULL,
#Verified_Date datetime = NULL
)
AS
BEGIN
SET NOCOUNT ON
IF #mode = 'Post_Query'
BEGIN
DECLARE #sql NVARCHAR(MAX)
if (#Query_Form is not null) and (#Patient_ID is not null) -- nu use in updating when no table or id is given
begin
SET #sql = N'Update #P0 ' +
'set Verified_By = #P1, ' +
' Verified_Date = #P2 ' +
'where Patient_ID = #P3'
EXEC sp_executesql #sql,
N'#P0 varchar(20), #P1 bigint, #P2 bigint, #P3 datetime',
N'#P0 = #Query_Form, #P1 = #Verified_By, #P2 = #Verified_Date, #P3 = #Patient_ID'
end
END
END

Appending variables inside dynamic sql in sql server

I'm having trouble building a dynamic sql string to run an openquery. When I print the query string it evaluates the variable name as string instead of the actual value. Here's what I have:
Declare #tsql varchar(1000)
Declare #book_review_start as date
Declare #book_review_end as date
set #book_review_start = convert(varchar(10),DATEADD(month, DATEDIFF(month, 0, GETDATE())-2, 0), 120)
set #book_review_end = convert(varchar(10), DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), -2), 120)
Set #tsql = 'select * from openquery(authorsdb, ''select distinct ssn as bsn
from authors.dbo.nytimes where review_date between '' + #book_review_start + 'and' + '#book_review_end' + 'and review = 'annual'
and city_name = ''
and review_hrs = 0
and review_days = 0')'
That throws all kinds of conversion errors and such.
1) You need 1 or more extra ' single quote characters in 1 or more places in your statement.
2) The DATE values need to converted to string / VARCHAR since you are concatenating string to generate the dynamic SQL statement.
The following works.
DECLARE #tsql VARCHAR(1000)
DECLARE #book_review_start AS DATE
DECLARE #book_review_end AS DATE
SET #book_review_start = DATEADD(month, DATEDIFF(month, 0, GETDATE())-2, 0)
set #book_review_end = DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), -2)
Set #tsql = 'SELECT * FROM OPENQUERY(authorsdb, ''SELECT DISTINCT ssn AS bsn FROM authors.dbo.nytimes WHERE review_date BETWEEN'''
+ CONVERT(varchar(20),#book_review_start) + ''' AND ''' + CONVERT(varchar(20),#book_review_end ) + ''''
+ ' AND review = ''annual'' AND city_name = '''' AND review_hrs = 0 AND review_days = 0 )'
PRINT #tsql
The OUTPUT of the PRINT Statement is as follows.
SELECT * FROM OPENQUERY(authorsdb, 'SELECT DISTINCT ssn AS bsn FROM
authors.dbo.nytimes WHERE review_date BETWEEN'2016-05-01' AND
'2016-06-30' AND review = 'annual' AND city_name = '' AND review_hrs =
0 AND review_days = 0 )
If the intent is to eventually do this:
exec sp_executesql #tsql
then, as a minimum you must:
1 Make #tsql an nvarchar variable as opposed to varchar.
2 As suggested by Serg, all single quotes in the sql part become 4 single quotes. For example, this:
and city_name = ''
becomes this:
and city_name = ''''''''
3 You need spaces around words. For example this:
where review_date between '' + #book_review_start + 'and'
must be this:
where review_date between ' + #book_review_start + ' and '
This should get you started. Read the other answers as well.
Your query issues are
- #book_review_start / end declared DATE, should be VARCHAR to take part in concatenation
- to have a quote in a quoted string you need double quote, to have quoted string in a quoted string you need 4 quotes
Try
Declare #tsql varchar(1000)
Declare #book_review_start varchar(10)
Declare #book_review_end varchar(10)
set #book_review_start = convert(varchar(10),DATEADD(month, DATEDIFF(month, 0, GETDATE())-2, 0), 120)
set #book_review_end = convert(varchar(10), DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), -2), 120)
Set #tsql = 'select * from openquery(authorsdb, ''select distinct ssn as bsn
from authors.dbo.nytimes where review_date between ''''' + #book_review_start + ''''' and ''''' + #book_review_end + ''''' and review = ''''annual''''
and city_name = ''''''''
and review_hrs = 0
and review_days = 0'')' ;
select #tsql;

How to use DATETime Column in dynamic query in sql server?

I have a Stored Proc which is using for Search Applicants is written as below:
/*
AUTHOR :
CREATION DATE :
NOTES :
PURPOSE :
MODIFIED BY :
MODIFICATION DATE :
*/
ALTER PROCEDURE USP_GET_ApplicantByFilter
(
#ApplicantName VARCHAR(100)='Ram',
#AgeFrom INT=0,
#AgeTo INT=0,
#Experience INT=0,
#ExperienceMonths INT=0,
#City VARCHAR(100)='',
#QualificationID INT=0,
#PositionID INT=0,
#ApplyDateFrom DATETIME='2010-06-29 00:00:00.000',
#ApplyDateTo DATETIME=NULL,
#SortColumn Varchar(128)='ApplicantID',
#SortDirection Varchar(56)='desc',
#Page int=1,
#RecsPerPage int =10
)
AS
DECLARE #SQL VARCHAR(MAX)
DECLARE #DSQL VARCHAR(MAX)
DECLARE #whereCondition VARCHAR(1024)
DECLARE #FirstRec int, #LastRec int
SET #FirstRec = (#Page - 1) * #RecsPerPage
SET #LastRec = (#Page * #RecsPerPage + 1)
Declare #SectionCount int;
Set NoCount On
Begin
SET #SQL='Select ROW_NUMBER() over( order by '+#SortColumn + ' ' +#SortDirection +') rownum, tblApplicants.ApplicantID, tblApplicants.ApplicantName, tblApplicants.FatherName, tblApplicants.DateOfBirth, tblApplicants.QualificationID, tblApplicants.EMailID, tblApplicants.Address, tblApplicants.City, tblApplicants.State, tblApplicants.Phone,
tblApplicants.ApplyDate, tblApplicants.PositionID, tblApplicants.isActive, tblPositionMaster.PositionName
FROM tblApplicants INNER JOIN tblPositionMaster ON tblApplicants.PositionID = tblPositionMaster.PositionID
WHERE 1=1 AND tblApplicants.isActive=1 '
if #ApplicantName!=''
begin
SET #sql +=' AND tblApplicants.ApplicantName like ''%'+ #ApplicantName +'%'''
end
if #AgeFrom!=0
begin
SET #SQL+=' AND DATEDIFF(YEAR,tblApplicants.DateOfBirth, GETDATE()) >= '+#AgeFrom
end
if #AgeTo!=0
begin
SET #SQL+=' AND DATEDIFF(YEAR,tblApplicants.DateOfBirth, GETDATE()) <= '+#AgeTo
end
if #ApplyDateFrom IS NOT NULL
begin
SET #SQL+= ' AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ CONVERT(DATETIME,#ApplyDateFrom,101)
end
SET #DSQL ='SELECT * from (' + #SQL +') AS tbl'
print #DSQL
DECLARE #TEMPResult TABLE(RowNum INT,
ApplicantID int,
ApplicantName varchar(100),
FatherName varchar(200),
DateOfBirth DATETIME,
QualificationID int,
EMailID varchar(200),
Address varchar(200),
City varchar(200),
State varchar(200),
Phone varchar(200),
ApplyDate DATETIME,
PositionID int,
isActive int,
PositionName varchar(200)
)
INSERT INTO #TEMPResult EXEC(#DSQL)
SELECT (Select Count(*) from #TEMPResult) as Count, * FROM #TEMPResult WHERE RowNum > #FirstRec AND RowNum < #LastRec
RETURN
END
i want to apply "=>" and "<=" operators on ApplyDate. every time i got "*Conversion failed when converting date and/or time from character string.
*"
please help me how can apply these operators on ApplDate
SET #SQL+= ' AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ CONVERT(DATETIME, #ApplyDateFrom, 101)
change it to:
SET #SQL+= ' AND CONVERT(DATETIME, tblApplicants.ApplyDate, 101) = CONVERT(DATETIME, ''' + cast(#ApplyDateFrom as nvarchar) + ''', 101)'
Replace this line
AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ CONVERT(DATETIME,#ApplyDateFrom,101)
Updated
AND DATEDIFF(DD,tblApplicants.ApplyDate, CAST(''' + CAST(#ApplyDateFrom as varchar) + ''' as datetime)) = 0
for more look this query
DECLARE #ApplyDateFrom DATETIME='2010-06-29 00:00:00.000'
DECLARE #QUERY varchar(max)
SET #QUERY =
'SELECT DATEDIFF(DD,GETDATE(), CAST(''' + CAST(#ApplyDateFrom as varchar) + ''' as datetime))'
PRINT #QUERY
#AgeFrom is an int. You need to convert it to a varchar before concatentating it to a string.
'AND DATEDIFF(YEAR,tblApplicants.DateOfBirth, GETDATE()) >= '+convert(varchar(5),#AgeFrom)
Not that this will work, of course, as datediff(year... won't give you an age. eg:
select DATEDIFF(YEAR,'2000-12-25','2013-10-01')
will return 13, not 12.
Similarly for ApplyDate convert that to a string
CONVERT(DATE,tblApplicants.ApplyDate,101) = ''' + CONVERT(varchar(20),#ApplyDateFrom,111) + ''''
To be honest though, this whole approach looks like a bad idea to me.
you just need to make sure the parameter before it come into your stored procedured is in this format yyyy-MM-dd HH:mm:ss
then you're save to compare using "<=" and ">=" and doesn't need to convert it to other format just compare like this
tblApplicants.ApplyDate >='2013-10-01 18:00:00'
You need to cast applydate to string before concatenate to dynamics sql.
Mean
SET #SQL+= ' AND CONVERT(DATETIME,tblApplicants.ApplyDate,101) ='+ cast (CONVERT(DATETIME,#ApplyDateFrom,101) AS VARCHAR)