August 29, 2013 at 3:28 pm
This syntax
SET @sql = 'SELECT * FROM <sometable> WHERE dateadd(hh, ''' + @tzoffset + '''), END_DATETIME) BETWEEN ''' + @StartDate + ''' AND ''' + @EndDate + ''''
returns this error
Conversion failed when converting the varchar value 'SELECT * FROM <sometable> WHERE dateadd(hh, '' to data type int.
How do I get around this?
August 29, 2013 at 3:45 pm
Hard to tell, but I'd bet one of your @variables is declared as int rather than varchar so the '+' becomes an addition operator rather than a concatenation operator. When concatenating, everything needs to be char or varchar.
August 29, 2013 at 3:56 pm
It's as simple as this:
SET @sql = 'SELECT * FROM <sometable>
WHERE dateadd(hh, @tzoffset, END_DATETIME) BETWEEN @StartDate AND @EndDate'
When you work with dynamic SQL you should use parameterised statements for many reasons, and one is exactly that it is simpler.
The way you run the query is this:
EXEC sp_executesql @sql, N'@tzoffset smallint, @StartDate datetime, @EndDate datetime',
@tzoffset, @StartDate, @EndDate
You can read more about sp_executesql in my article on dynamic SQL:
http://www.sommarskog.se/dynamic_sql.html#sp_executesql
By the way, I think a better solution is
SET @sql = 'SELECT * FROM <sometable>
WHERE END_DATETIME BETWEEN dateadd(hh, -@tzOffset, @StartDate) AND dateadd(hh, -@tzOffset, @EndDate'
While longer, the first solution runs the risk that the optimzer will not use any index on END_DATETIME.
[font="Times New Roman"]Erland Sommarskog, SQL Server MVP, www.sommarskog.se[/font]
August 29, 2013 at 4:27 pm
David, Thank you. I will keep that in mind.
Erland, I think this is exactly the information I needed! I will post back tomorrow when I know for sure it works.
Rebecca
August 29, 2013 at 10:41 pm
rebecca 79612 (8/29/2013)
This syntaxSET @sql = 'SELECT * FROM <sometable> WHERE dateadd(hh, ''' + @tzoffset + '''), END_DATETIME) BETWEEN ''' + @StartDate + ''' AND ''' + @EndDate + ''''
returns this error
Conversion failed when converting the varchar value 'SELECT * FROM <sometable> WHERE dateadd(hh, '' to data type int.
How do I get around this?
Why do you need this to be dynamic SQL? You're not dynamically changing anything that requires dynamic SQL unless you're changing <sometable> to something else.
--Jeff Moden
Change is inevitable... Change for the better is not.
August 30, 2013 at 6:29 am
Declare all variable used in dynamic query as nvarchar or varchar. It will work for sure.
August 30, 2013 at 7:04 am
churi.hrushikesh (8/30/2013)
Declare all variable used in dynamic query as nvarchar or varchar. It will work for sure.
Better than that, don't use dynamic SQL because it doesn't look like it's even needed here. 😉
--Jeff Moden
Change is inevitable... Change for the better is not.
August 30, 2013 at 8:44 am
Erland,
Thank you very much. This solved my problem and works on the ACTUAL query I am using and not just the simple version posted on the forum.
Also, I cannot tell you how many times I have visited (and printed) the article 'The curse and blessings of dynamic SQL' over the last couple of years! Thank you for your effort in writing the article. It has served me well. Obviously I need to visit it a little more. 😉
Rebecca
August 30, 2013 at 9:15 am
You may find that the following will work better as the execution plans will more likely be cached, plus it will use an index on END_DATETIME if it exists and will help the query. Your code will require a table or clustered index scan since the DATEADD function will have to applied to every row in the table to determine if the criteria matches or not.
DECLARE @SQLCmd NVARCHAR(MAX),
@SQLParam NVARCHAR(MAX),
@StartDate1 DATETIME,
@EndFate1 DATETIME,
@tzoffset1 INT;
SET @SQLCmd = N'
SELECT *
FROM <sometable>
WHERE
END_DATETIME between DATEADD(hh, -1 * @tzoffset , @StartDate) and DATEADD(hh, -1 * @tzoffset , @EndDate)
';
SET @SQLParam = N'@StartDate DATETIME, @EndDate DATETIME, @tzoffset INT';
EXEC sp_executesql @SQLCmd, @SQLParam, @StartDate = @StartDate1, @EndDate = @EndFate1, @tzoffset = @tzoffset1;
August 30, 2013 at 10:18 am
Lynn,
:w00t: Ah, yes I see what you mean. Thank you for further insight on this solution!
September 3, 2013 at 2:10 pm
You don't want to use a function against the END_DATETIME column if you can avoid it, since any function will prevent SQL from using the full seek capabilities against that column in any index(es) in which it might appear.
I think the code below will do SELECT the same rows as your original query, but adjust the code if/as needed to match you need:
SELECT *
FROM dbo.tablename
WHERE
END_DATETIME >= DATEADD(HOUR, -@tzoffset, @StartDate) AND
END_DATETIME <= DATEADD(HOUR, -@tzoffset, @EndDate)
SQL DBA,SQL Server MVP(07, 08, 09) "It's a dog-eat-dog world, and I'm wearing Milk-Bone underwear." "Norm", on "Cheers". Also from "Cheers", from "Carla": "You need to know 3 things about Tortelli men: Tortelli men draw women like flies; Tortelli men treat women like flies; Tortelli men's brains are in their flies".
September 4, 2013 at 3:53 am
ScottPletcher (9/3/2013)
You don't want to use a function against the END_DATETIME column if you can avoid it, since any function will prevent SQL from using the full seek capabilities against that column in any index(es) in which it might appear.I think the code below will do SELECT the same rows as your original query, but adjust the code if/as needed to match you need:
SELECT *
FROM dbo.tablename
WHERE
END_DATETIME >= DATEADD(HOUR, -@tzoffset, @StartDate) AND
END_DATETIME <= DATEADD(HOUR, -@tzoffset, @EndDate)
Same thing I suggested in my post.
Viewing 12 posts - 1 through 11 (of 11 total)
You must be logged in to reply to this topic. Login to reply