我试着四处寻找但找不到任何可以帮助我的东西.
我正在尝试在SQL中执行此操作:
declare @locationType varchar(50); declare @locationID int; SELECT column1, column2 FROM viewWhatever WHERE CASE @locationType WHEN 'location' THEN account_location = @locationID WHEN 'area' THEN xxx_location_area = @locationID WHEN 'division' THEN xxx_location_division = @locationID
我知道我不应该在每个人的末尾放置'= @locationID',但我无法使语法接近正确.SQL在第一条WHEN行上一直抱怨我的'='
救命!
declare @locationType varchar(50); declare @locationID int; SELECT column1, column2 FROM viewWhatever WHERE @locationID = CASE @locationType WHEN 'location' THEN account_location WHEN 'area' THEN xxx_location_area WHEN 'division' THEN xxx_location_division END
没有案例陈述......
SELECT column1, column2 FROM viewWhatever WHERE (@locationType = 'location' AND account_location = @locationID) OR (@locationType = 'area' AND xxx_location_area = @locationID) OR (@locationType = 'division' AND xxx_location_division = @locationID)
干得好.
SELECT column1, column2 FROM viewWhatever WHERE CASE WHEN @locationType = 'location' AND account_location = @locationID THEN 1 WHEN @locationType = 'area' AND xxx_location_area = @locationID THEN 1 WHEN @locationType = 'division' AND xxx_location_division = @locationID THEN 1 ELSE 0 END = 1
我会说这是一个有缺陷的表结构的指标.也许不同的位置类型应该在不同的表中分开,这使您可以进行更丰富的查询,并避免使用多余的列.
如果您无法更改结构,则可能会执行以下操作:
SELECT * FROM Test WHERE Account_Location = ( CASE LocationType WHEN 'location' THEN @locationID ELSE Account_Location END ) AND Account_Location_Area = ( CASE LocationType WHEN 'area' THEN @locationID ELSE Account_Location_Area END )
等等...我们无法动态更改查询的结构,但我们可以通过使谓词等于自己来覆盖它.
编辑:以上建议当然要好得多,只是忽略我的.
这样做的问题是,当SQL引擎去评估表达式时,它将检查FROM部分以提取适当的表,然后检查WHERE部分以提供一些基本条件,因此它无法正确地评估要在哪一列上使用的动态条件。检查。
在检查谓词中的WHERE条件时,可以使用WHERE子句,例如
WHERE account_location = CASE @locationType WHEN 'business' THEN 45 WHEN 'area' THEN 52 END
因此,在您的特定情况下,您需要将查询放入存储过程或创建三个单独的查询。
在运行条件的情况下,OR运算符可以替代大小写
ALTER PROCEDURE [dbo].[RPT_340bClinicDrugInventorySummary] -- Add the parameters for the stored procedure here @ClinicId BIGINT = 0, @selecttype int, @selectedValue varchar (50) AS BEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; SELECT drugstock_drugname.n_cur_bal,drugname.cdrugname,clinic.cclinicname FROM drugstock_drugname INNER JOIN drugname ON drugstock_drugname.drugnameid_FK = drugname.drugnameid_PK INNER JOIN drugstock_drugndc ON drugname.drugnameid_PK = drugstock_drugndc.drugnameid_FK INNER JOIN drugndc ON drugstock_drugndc.drugndcid_FK = drugndc.drugid_PK LEFT JOIN clinic ON drugstock_drugname.clinicid_FK = clinic.clinicid_PK WHERE (@ClinicId = 0 AND 1 = 1) OR (@ClinicId != 0 AND drugstock_drugname.clinicid_FK = @ClinicId) -- Alternative Case When You can use OR AND ((@selecttype = 1 AND 1 = 1) OR (@selecttype = 2 AND drugname.drugnameid_PK = @selectedValue) OR (@selecttype = 3 AND drugndc.drugid_PK = @selectedValue) OR (@selecttype = 4 AND drugname.cdrugclass = 'C2') OR (@selecttype = 5 AND LEFT(drugname.cdrugclass, 1) = 'C')) ORDER BY clinic.cclinicname, drugname.cdrugname END