Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL查询中的动态WHERE子句_Sql_Sql Server_Stored Procedures - Fatal编程技术网

SQL查询中的动态WHERE子句

SQL查询中的动态WHERE子句,sql,sql-server,stored-procedures,Sql,Sql Server,Stored Procedures,我想执行这个查询 select * from locations where region=1 or region=2 但在某些情况下,我不想在WHERE(或region=2)中包含第二个子句 有没有办法有条件地运行or语句?检查where语句中的条件 DECLARE @RUNAFTERBIT VARCHAR(10) SET @RUNAFTERBIT = 'TRUE' IF @RUNAFTERBIT = 'TRUE' SELECT * FROM LOCATIONS WHERE REGIO

我想执行这个查询

select * from locations where region=1 or region=2
但在某些情况下,我不想在WHERE(
或region=2
)中包含第二个子句
有没有办法有条件地运行or语句?

检查where语句中的条件

DECLARE @RUNAFTERBIT VARCHAR(10)
SET @RUNAFTERBIT = 'TRUE'

IF @RUNAFTERBIT = 'TRUE'
  SELECT * FROM LOCATIONS WHERE REGION = 1 OR REGION = 2
ELSE
  SELECT * FROM LOCATIONS WHERE REGION = 1 
END IF
select * from locations 
where region=1 
or (region=2 and @checkRegion2=1)

检查where语句中的条件

select * from locations 
where region=1 
or (region=2 and @checkRegion2=1)

如果您想要可genralizable查询,可以为此声明表变量(假设您使用的是SQL server):

然后根据情况加注:

insert into @regions select 1
if @use2 = 1
    insert into @regions select 2
现在可以运行此查询:

select *
from location as l
where exists (select * from @regions as r where r.id = l.region)


如果您想要可genralizable查询,可以为此声明表变量(假设您使用的是SQL server):

然后根据情况加注:

insert into @regions select 1
if @use2 = 1
    insert into @regions select 2
现在可以运行此查询:

select *
from location as l
where exists (select * from @regions as r where r.id = l.region)


您可以使用动态SQL:

DECLARE @Query VARCHAR(MAX) = 'SELECT * FROM locations WHERE region=1 '

IF(@RUNAFTERBIT = 'TRUE')
BEGIN
    SET @Query = @Query + ' OR REGION = 2'
END

EXEC(@Query)

您可以使用动态SQL:

DECLARE @Query VARCHAR(MAX) = 'SELECT * FROM locations WHERE region=1 '

IF(@RUNAFTERBIT = 'TRUE')
BEGIN
    SET @Query = @Query + ' OR REGION = 2'
END

EXEC(@Query)

在某些情况下,
情况
表达式可用于执行短路评估:

declare @AlternateRegion as Int = 2;

select *
  from Locations
  where case
    when Region = 1 then 1
    when @AlternateRegion is not NULL then
      case when Region = @AlternateRegion then 1 else 0 end
    else 0
    end = 1

案例
在存在聚合功能的情况下不能可靠地提供短路评估。请参阅和。

在某些情况下,表达式可用于执行短路评估:

declare @AlternateRegion as Int = 2;

select *
  from Locations
  where case
    when Region = 1 then 1
    when @AlternateRegion is not NULL then
      case when Region = @AlternateRegion then 1 else 0 end
    else 0
    end = 1

案例
在存在聚合功能的情况下不能可靠地提供短路评估。请参阅和。

或使用连接:
从位置选择*作为l内部连接@区域作为r在r.region=l.region
(应该可以工作,未经测试,在浏览器中键入,没有SQL Server可供测试,…您知道这个练习)@MichaelKjörling yep,但我更喜欢
中的
存在的
,因为它清楚地表明我不需要@regions表中的任何字段,只想从location中筛选出行或使用连接:
select*from location as l internal join@regions as r on r.region=l.region
(应该可以工作,未经测试,在浏览器中键入,没有SQL Server可供测试,…你知道这个练习)@MichaelKjörling yep,但我更喜欢
中或
存在
,因为它清楚地表明我不需要@regions表中的任何字段,只想从location中筛选出行。我强烈建议对于可维护代码,您应该显式命名列,而不是使用
选择*
。如果问题中的代码仅用于说明,则此注释可能不适用。我强烈建议,对于可维护的代码,应明确命名列,而不是使用
select*
。如果问题中的代码仅用于说明,则此注释可能不适用。但请不要。试着想出一些不涉及动态SQL的方法。您失去了参数保护、代码可读性、查询编译和执行计划缓存,可能还有一大堆其他东西。充其量也一样。在最坏的情况下,你会牺牲大量的性能而得不到任何好处。@MichaelKjörling通常,动态SQL是我做这类事情的最后一种方法,但是根据我的经验,有时它甚至可以表现得更好(如果where情况非常复杂,并且取决于许多参数)。在这种情况下当然不会,但请不要。试着想出一些不涉及动态SQL的方法。您失去了参数保护、代码可读性、查询编译和执行计划缓存,可能还有一大堆其他东西。充其量也一样。在最坏的情况下,你会牺牲大量的性能而得不到任何好处。@MichaelKjörling通常,动态SQL是我做这类事情的最后一种方法,但是根据我的经验,有时它甚至可以表现得更好(如果where情况非常复杂,并且取决于许多参数)。当然不是在这种情况下