Reputation: 5044
I am using a dynamic query wherein I want to use the variable which holds the datetime, whenever I execute the query it says cannot convert datetime from string, when I cast that variable to varchar(max)
, it takes it as string and not datetime
, so how should I execute the query..
Below is my SQL query which I am trying to execute.
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity,
CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE FROM '+@TABLE+' B
WHERE B.TillDate BETWEEN CONVERT(VARCHAR(10),'+@FROMDATE+', 101) and
CONVERT(VARCHAR(10), DATEADD(DD,1,'+@TODATE+'), 101)'
EXEC SP_EXECUTESQL @SQL1
here @fromdate
and @todate
are the datetime
type coming from different temp table. and stored in these variable..
How should I execute this query?
Upvotes: 12
Views: 97042
Reputation: 1060
I needed to pass a date as a variable to a stored procedure I was executing within the dynamic SQL:
Declare @asOfDate date = '2020-01-01'
Declare @sql nvarchar(max)
Set @sql='SELECT * FROM OPENROWSET(''SQLNCLI''
,''Server=localhost;Database=YOURDB;Uid=DBO_DB;Pwd=password''
,''SET FMTONLY OFF;SET NOCOUNT ON;
declare @date date ;
select @date = CONVERT(DATE,CONVERT(varchar(10),'+ CONVERT(VARCHAR(100),@asOfDate , 112)+'));
exec your_proc_here @date
'')'
Print @sql
--Exec(@sql)
Upvotes: 0
Reputation: 1
Run this example and adapt it to your code. (There are not 3 contiguous single quotes)
Declare @FromDATE datetime
;Declare @ToDATE datetime
;set @FromDATE = getdate()
;set @ToDATE = @FromDATE
;Print 'WHERE TillDate BETWEEN ' + char(39) + CONVERT(VARCHAR(10),@FromDATE, 101)
+ char(39) + ' and ' + char(39) + CONVERT(VARCHAR(10),@ToDATE, 101) + char(39)
Upvotes: 0
Reputation: 11908
You should not concatenate your parameter values like this. The best solution is to use a parameterized query with sp_executesql.
DECLARE @sql nvarchar(4000)
select @sql = N'
SELECT B.FacId
, B.FacName
, B.BookCode
, B.BookName
, B.Quantity
, CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE
FROM ' + quotename(@TABLE) + N' B
WHERE B.TillDate BETWEEN cast(floor(cast(@fromDate as float)) as datetime)
AND cast(floor(cast(@toDate as float)) as datetime)'
EXEC sp_executesql @sql, N'@fromDate datetime, @toDate datetime', @FROMDATE, @TODATE
Things to note about sp_executesql are:
NVARCHAR
valuesSome additional changes were applied to the query:
QUOTENAME()
function which protects against sql injection on the object nameconvert(,,101)
is an expensive operation which can better be done using the casting to float and taking floor of that value.Upvotes: 9
Reputation: 3604
You need to quote your dates..
SET @SQL1 =
'SELECT B.FacId,
B.FacName,
B.BookCode,
B.BookName,
B.Quantity,
CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE
FROM '+@TABLE+' B
WHERE B.TillDate BETWEEN ''' + CONVERT(VARCHAR(10),@FROMDATE, 101) + ''' and ''' + CONVERT(VARCHAR(10),DATEADD(DD,1,@TODATE), 101) + ''''
Upvotes: 38
Reputation: 151
I think this might work:
DECLARE @tempdate datetime
SET tempdate =DATEADD(DD,1,@TODATE)
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity,'''+ cast (B.TillDate as VARCHAR(50))+''' AS TILLDATE FROM '+@TABLE+' B WHERE B.TillDate BETWEEN '''+cast(@FROMDATE as VARCHAR(50))+''' and '''+cast(@tempdate as VARCHAR(50))'''
EXEC SP_EXECUTESQL @SQL1
Upvotes: 2
Reputation: 1764
This is late, but may be it help someone
What you need is a quotes around your date, You already got your answer.
Below is an example of what I usually put in my query
'(CONVERT(DATETIME,CONVERT(varchar,gd.CreatedDate),106) <= CONVERT(DATETIME,'''+CONVERT(varchar, @EndDate ) +''',106))'
note that @EndDate is of type Datetime here
Upvotes: 0
Reputation: 1316
I'd like to see your variable definitions but I suspect it's because @FROMDATE and @TODATE are datetime and you're using them in a string concatenation statement. Thus you can fix it by:
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity, CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE FROM '+@TABLE+' B WHERE B.TillDate BETWEEN CONVERT(VARCHAR(10),'+CAST(@FROMDATE as varchar(15))+', 101) and CONVERT(VARCHAR(10), DATEADD(DD,1,'+CAST(@TODATE as varchar(15))+'), 101)'
However better solutions are:
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity, B.TillDate AS TILLDATE FROM '+@TABLE+' B
WHERE B.TillDate BETWEEN @inFROMDATE and @inTODATE'
EXEC SP_EXECUTESQL @SQL1,'@inFROMDATE datetime, @inTODATE',@inFromDate = @FROMDATE, @inTODATE = @TODate
Upvotes: 2
Reputation: 11966
Try this:
declare @sql1 varchar(max)
declare @table sysname
declare @FROMDATE datetime
declare @TODATE datetime
set @table = 'MyTable'
set @FROMDATE = GETDATE()
set @ToDATE = GETDATE()
SET @SQL1 = 'SELECT B.FacId, B.FacName, B.BookCode, B.BookName, B.Quantity,
CONVERT(VARCHAR(10), B.TillDate, 104) AS TILLDATE FROM '+@TABLE+' B
WHERE B.TillDate BETWEEN CONVERT(Datetime,''' + CONVERT(VARCHAR(10),@FROMDATE, 101)
+ ''', 101) and CONVERT(DATETIME,'''+ CONVERT(VARCHAR(10), DATEADD(DD,1,@TODATE), 101) + ''', 101)'
print @sql1
But look at Joel Mansford's answer to avoid the double conversion.
Upvotes: 0