Sql server 如何在SQL Server查询中联系动态@where子句?
我已根据SQL Server中选择的选项创建了一个动态Sql server 如何在SQL Server查询中联系动态@where子句?,sql-server,Sql Server,我已根据SQL Server中选择的选项创建了一个动态where子句,但当我在SQL查询的末尾添加此动态where字符串时,我收到以下错误消息: 转换varchar值“Where…”时失败。。。。。到数据类型 整数 这是我的疑问: lter PROCEDURE [dbo].[GetDailyLogSearchReportLegalNew] @FilterBy varchar(100),@BranchFilter varchar(100), @Status varchar(100), @dtFr
where
子句,但当我在SQL查询的末尾添加此动态where
字符串时,我收到以下错误消息:
转换varchar值“Where…”时失败。。。。。到数据类型
整数
这是我的疑问:
lter PROCEDURE [dbo].[GetDailyLogSearchReportLegalNew] @FilterBy varchar(100),@BranchFilter varchar(100), @Status varchar(100), @dtFrom date, @dtTo date
AS
-- exec GetDailyLogSearchReportLegalnew @FilterBy = 'BRANCH',@BranchFilter = 'CHICAGO',@Status ='B', @dtFrom = '06-01-2015', @dtTo ='07-24-2015'
declare @Query NVARCHAR(Max)
declare @Where varchar(1000)
declare @Query1 NVARCHAR(Max)
declare @Where1 varchar(1000)
declare @Merge NVARCHAR(Max)
if(@FilterBy = 'BRANCH' and @BranchFilter = 'ALL')
BEGIN
if(@Status = 'B')
BEGIN
set @Where = ' Where
LG_BillTo=0 AND dbo.LegalMain.LG_ReceivedDate >= '+''''+ convert(varchar(25),Convert(date,@dtFrom)) +' '+'00:00:00.000'' AND dbo.LegalMain.LG_ReceivedDate <= '''+ convert(varchar(25),Convert(date,@dtTo)) +' '+'23:59:59.999'''
END
else if(@Status = 'C')
BEGIN
set @Where = 'WHERE
LG_BillTo=0 AND dbo.LegalMain.LG_ActualDateCompleted >= '+''''+ convert(varchar(25),Convert(date,@dtFrom)) +' '+'00:00:00.000'' AND dbo.LegalMain.LG_ActualDateCompleted <= '''+ convert(varchar(25),Convert(date,@dtTo)) +' '+'23:59:59.999'''
END
else if(@Status = 'I')
BEGIN
set @Where = 'WHERE
LG_BillTo=0 AND dbo.LegalMain.LG_ReceivedDate >= '+''''+ convert(varchar(25),Convert(date,@dtFrom)) +' '+'00:00:00.000'' AND dbo.LegalMain.LG_ReceivedDate <= '''+ convert(varchar(25),Convert(date,@dtTo)) +' '+'23:59:59.999'' And dbo.LegalMain.LG_ActualDateCompleted is null'
END
END
SELECT LEFT(LG_CreationTime,5) as 'Status', dbo.LegalMain.LG_LegalID AS ID,
dbo.LegalMain.LG_ReceivedDate AS 'Received Date', Forwarder.CST_ShortName AS 'Customer',
dbo.City.CTY_CityName AS 'City', Shipper.CST_FullName AS 'Shipper',
dbo.LegalMain.LG_ReferenceNo AS 'Ref No', dbo.Country.CNT_CountryName AS 'Country',
dbo.LegalBranch.BR_BranchName AS Branch, ST_ServiceType AS 'Service Type',
dbo.LegalMain.LG_ActualDateCompleted AS NewCompleted,
SN_SentTo as 'Sent To',LG_COPREP as CO, LG_InoviceNo AS 'Invoice No'
FROM dbo.LegalBranch
RIGHT OUTER JOIN dbo.LegalMain ON dbo.LegalBranch.BR_ID = dbo.LegalMain.LG_BranchId
LEFT OUTER JOIN dbo.Country ON dbo.LegalMain.LG_CountryID = dbo.Country.CNT_CountryID
LEFT OUTER JOIN dbo.Customer AS Forwarder
LEFT OUTER JOIN dbo.City ON Forwarder.CST_CityID = dbo.City.CTY_CityID ON dbo.LegalMain.LG_ForwarderID = Forwarder.CST_CustomerID
LEFT OUTER JOIN dbo.LegalServiceType ON dbo.LegalMain.LG_ServiceTypeId = dbo.LegalServiceType.ST_ServiceTypeID
LEFT OUTER JOIN dbo.LegalSentTo ON dbo.LegalMain.LG_SentToId = dbo.LegalSentTo.SN_ID
LEFT OUTER JOIN dbo.Customer AS Shipper ON dbo.LegalMain.LG_ShipperID = Shipper.CST_CustomerID & ' ' & cast(@Where as varchar(1000))
lter过程[dbo]。[GetDailyLogSearchReportLegalNew]@FilterBy varchar(100)、@BranchFilter varchar(100)、@Status varchar(100)、@dtFrom date、@dtTo date
作为
--exec GetDailyLogSearchReportLegalnew@FilterBy='BRANCH',@BranchFilter='芝加哥',@Status='B',@dtFrom='06-01-2015',@dtTo='07-24-2015'
声明@Query NVARCHAR(最大值)
声明@Where varchar(1000)
声明@Query1 NVARCHAR(最大值)
声明@Where1 varchar(1000)
声明@Merge-NVARCHAR(最大值)
if(@FilterBy='BRANCH'和@BranchFilter='ALL')
开始
如果(@Status='B')
开始
设置@Where='Where
LG_BillTo=0和dbo.LegalMain.LG_ReceivedDate>='+''''转换(varchar(25),convert(date,@dtFrom))+'+'00:00:00.000''和dbo.LegalMain.LG_ReceivedDate='+''''转换(varchar 25,convert(date,@dtFrom))+'+'+''+'00:00:00.000''和dbo.LegalMain实际完成日期='+''+转换(varchar 25,convert(date,@dtFrom))++'+'00:00:00.000''和dbo.LegalMain.LG_ReceivedDate问题在于您将代码和内容混为一谈;包含代码的变量不会自动转换为可执行的内容;系统不理解你的意图
相反,创建要在变量中运行的完整代码,然后告诉SQL执行该变量中包含的代码
Declare @myWhere nvarchar(max)
, @mySql nvarchar(max)
--for the sake of illistration
set @myWhere = 'where ID < 200'
set @mySql = 'Select ID from myTable ' + @myWhere
exec sp_executesql @mySql
--or exec(@mySql)
您希望上述的输出是什么
此处为可运行版本:
更新
根据您修改后的问题/代码,以下内容可能会满足您的要求,而无需使用动态SQL
SELECT LEFT(LG_CreationTime,5) as 'Status'
, dbo.LegalMain.LG_LegalID AS ID
, dbo.LegalMain.LG_ReceivedDate AS 'Received Date'
, Forwarder.CST_ShortName AS 'Customer'
, dbo.City.CTY_CityName AS 'City'
, Shipper.CST_FullName AS 'Shipper'
, dbo.LegalMain.LG_ReferenceNo AS 'Ref No'
, dbo.Country.CNT_CountryName AS 'Country'
, dbo.LegalBranch.BR_BranchName AS Branch
, ST_ServiceType AS 'Service Type'
, dbo.LegalMain.LG_ActualDateCompleted AS NewCompleted
, SN_SentTo as 'Sent To'
, LG_COPREP as CO
, LG_InoviceNo AS 'Invoice No'
FROM dbo.LegalMain
LEFT OUTER JOIN dbo.LegalBranch
ON dbo.LegalBranch.BR_ID = dbo.LegalMain.LG_BranchId
LEFT OUTER JOIN dbo.Country
ON dbo.Country.CNT_CountryID = dbo.LegalMain.LG_CountryID
LEFT OUTER JOIN dbo.Customer AS Forwarder
ON Forwarder.CST_CustomerID = dbo.LegalMain.LG_ForwarderID
LEFT OUTER JOIN dbo.City
ON dbo.City.CTY_CityID = Forwarder.CST_CityID
LEFT OUTER JOIN dbo.LegalServiceType
ON dbo.LegalServiceType.ST_ServiceTypeID = dbo.LegalMain.LG_ServiceTypeId
LEFT OUTER JOIN dbo.LegalSentTo
ON dbo.LegalSentTo.SN_ID = dbo.LegalMain.LG_SentToId
LEFT OUTER JOIN dbo.Customer AS Shipper
ON Shipper.CST_CustomerID = dbo.LegalMain.LG_ShipperID
WHERE (NOT (@FilterBy = 'BRANCH' and @BranchFilter = 'ALL'))
OR
(
LG_BillTo = 0
AND
(
(
@Status = 'B'
AND dbo.LegalMain.LG_ReceivedDate between @dtFrom and DATEADD(second,-1,DATEADD(day,1,@dtTo))
)
OR
(
@Status = 'C'
AND dbo.LegalMain.LG_ActualDateCompleted between @dtFrom and DATEADD(second,-1,DATEADD(day,1,@dtTo))
)
OR
(
@Status = 'I'
AND dbo.LegalMain.LG_ReceivedDate between @dtFrom and DATEADD(second,-1,DATEADD(day,1,@dtTo))
And dbo.LegalMain.LG_ActualDateCompleted is null
)
)
)
注意:此代码未经测试,可能会执行得很糟糕,因为有很多连接/条件。我不建议在生产环境中使用此代码,而是让SQL开发人员提供帮助,指定您的功能需求,并向他们提供运行此功能的数据库副本。请显示一些代码。列是动态生成的还是动态传递给列的值您认为为什么需要“动态where”?动态SQL是一种非常强烈的气味,它会导致性能和安全问题,但毫无益处。如果要创建具有不同条件的查询,请在客户机上执行此操作,例如使用ORM或参数化查询代码很难阅读,但包含许多问题,例如将日期转换为文本以与日期列进行比较?字符串串联只会使检测转换或引用错误变得不可能。至少,创建一个视图,而不是在语句中连接所有这些表。这将删除至少11行错误在最后一行(@Where as varchar(1000))我们不能修复吗这是我的完整查询我不使用exec我只需要在查询中使用一个简单的select with Where子句不想使用sp的exec_executesql@Jim您必须使用exec
或更好的sp\u executesql
。更好的是,不要这样做。使用LINQ的ORM是使用更改的标准创建查询的更好选项错误在最后一行-“”&cast(@Where as varchar(1000))中我们不能修复吗it@Jim你为什么这么认为?很可能@Where语句无效。无论如何,不能用变量代替WHERE语句。SQL不是这样工作的。您必须创建一个字符串并使用exec
或sp_executesql
SELECT LEFT(LG_CreationTime,5) as 'Status'
, dbo.LegalMain.LG_LegalID AS ID
, dbo.LegalMain.LG_ReceivedDate AS 'Received Date'
, Forwarder.CST_ShortName AS 'Customer'
, dbo.City.CTY_CityName AS 'City'
, Shipper.CST_FullName AS 'Shipper'
, dbo.LegalMain.LG_ReferenceNo AS 'Ref No'
, dbo.Country.CNT_CountryName AS 'Country'
, dbo.LegalBranch.BR_BranchName AS Branch
, ST_ServiceType AS 'Service Type'
, dbo.LegalMain.LG_ActualDateCompleted AS NewCompleted
, SN_SentTo as 'Sent To'
, LG_COPREP as CO
, LG_InoviceNo AS 'Invoice No'
FROM dbo.LegalMain
LEFT OUTER JOIN dbo.LegalBranch
ON dbo.LegalBranch.BR_ID = dbo.LegalMain.LG_BranchId
LEFT OUTER JOIN dbo.Country
ON dbo.Country.CNT_CountryID = dbo.LegalMain.LG_CountryID
LEFT OUTER JOIN dbo.Customer AS Forwarder
ON Forwarder.CST_CustomerID = dbo.LegalMain.LG_ForwarderID
LEFT OUTER JOIN dbo.City
ON dbo.City.CTY_CityID = Forwarder.CST_CityID
LEFT OUTER JOIN dbo.LegalServiceType
ON dbo.LegalServiceType.ST_ServiceTypeID = dbo.LegalMain.LG_ServiceTypeId
LEFT OUTER JOIN dbo.LegalSentTo
ON dbo.LegalSentTo.SN_ID = dbo.LegalMain.LG_SentToId
LEFT OUTER JOIN dbo.Customer AS Shipper
ON Shipper.CST_CustomerID = dbo.LegalMain.LG_ShipperID
WHERE (NOT (@FilterBy = 'BRANCH' and @BranchFilter = 'ALL'))
OR
(
LG_BillTo = 0
AND
(
(
@Status = 'B'
AND dbo.LegalMain.LG_ReceivedDate between @dtFrom and DATEADD(second,-1,DATEADD(day,1,@dtTo))
)
OR
(
@Status = 'C'
AND dbo.LegalMain.LG_ActualDateCompleted between @dtFrom and DATEADD(second,-1,DATEADD(day,1,@dtTo))
)
OR
(
@Status = 'I'
AND dbo.LegalMain.LG_ReceivedDate between @dtFrom and DATEADD(second,-1,DATEADD(day,1,@dtTo))
And dbo.LegalMain.LG_ActualDateCompleted is null
)
)
)