我正在创建一个存储过程,其中我有一个main子句和一个where子句:
CREATE ROCEDURE [dbo].[spLocal_GetData]
@CreatedOnDate DateTime
AS
declare @MainQuery varchar(max),
@WhereClause varchar(1000)
Select @MainQuery = 'Select column from Table T1'
Select @WhereClause = ' Where T1.CreateOn >='+@CreatedOnDate
现在执行存储过程时:
DECLARE @CreatedOnDate datetime
SET @CreatedOnDate =GETDATE()
EXECUTE @RC = [dbo].[spLocal_GetData] ,@CreatedOnDate
GO
我收到错误:
从字符串转换日期和/或时间时转换失败。
EDIT1:
declare @MainQuery varchar(max),
@WhereClause varchar(1000)
Select @MainQuery =N'Select ..'
Select @WhereClause = N' Where T1.CreatedOn>=@CreatedOnDate'
EXECUTE @RC = [dbo].[spLocal_GetNonConformance]
,N'@CreatedOnDate DateTime'
GO
答案 0 :(得分:2)
您收到错误是因为您尝试将日期时间值与字符串' Where T1.CreateOn >='+@CreatedOnDate
连接起来,Datetime是一个更高优先级的数据类型,sql server尝试将字符串值转换为datetime并失败。
你的方法很容易sql注入你应该使用动态sql。虽然对于这个简单的查询,你甚至不需要动态的SQL,但假设实际的查询有点复杂,你实际上需要动态的SQL,你会这样做......
试试这个,它也可以保护你免受sql注入攻击......
CREATE ROCEDURE [dbo].[spLocal_GetData]
@CreatedOnDate DateTime
As
BEGIN
declare @MainQuery nvarchar(max)
SET @MainQuery = N'Select column from Table T1'
+ N' Where T1.CreateOn >= @CreatedOnDate'
Exec sp_executesql @MainQuery
,N'@CreatedOnDate DateTime'
,@CreatedOnDate
END
答案 1 :(得分:0)
您必须先将DateTime
转换为varchar
,然后再将其附加到动态sql
所以
Select @WhereClause =' Where T1.CreateOn >='+convert(varchar(20),@CreatedOnDate,120)
会为你效劳。