SQL Server 查询仅在没有变量为空时才有效

Posted

技术标签:

【中文标题】SQL Server 查询仅在没有变量为空时才有效【英文标题】:SQL Server query only works if no variables are empty 【发布时间】:2018-09-10 15:05:04 【问题描述】:

我正在尝试创建一个查询,该查询将根据不同的 html 下拉选择过滤表。我有 5 个单独的下拉菜单,每当我进行选择时,该值都会传递到一个查询中(并存储到清除为止),该查询会填充页面上的数据。但是,此查询仅在已做出所有选择时才显示数据。我也没有看到任何错误。有人可以向我解释为什么会发生这种情况并提供一个解决方案来解决无论已进行多少下拉选择的数据显示位置吗?

$q = ($_GET['q']);
$date = ($_GET['data']);
$val = ($_GET['val']);
$rep = ($_GET['rep']);
$group = ($_GET['group']);

$sql ="SELECT [Customer]
      ,[Collector Name]
      ,[Bill Date]
      ,[Days Until Next Action]
      ,[Next Action]
      ,[Next Bill Date]
      ,[Billed Status]
      ,[Billed Amount]
      ,[Total Current Balance]
      ,CAST([Payment Due Date] as DATE) as [Payment Due Date]
      ,[Notes]
      ,[Payment Status]
      ,[Line Status]
        FROM [Test_Spec_Bill]
        WHERE ([Collector Name] = '$q' OR datalength([Collector Name]) = 0)
        AND ([Date Group - Filter] = '$date' OR datalength([Date Group - Filter]) = 0)
        AND ([Billed Status] = '$val' OR datalength([Billed Status]) = 0)
        AND ([Parent Report Code] = '$rep' OR datalength([Parent Report Code]) = 0)
        AND ([Balance Group - Filter] = '$group' OR datalength([Balance Group - Filter]) = 0)

【问题讨论】:

你为什么要检查所有的数据长度?以及为什么要检查列而不是参数。 我认为您想更改 where 条件以使用 case 语句,例如: WHERE [Collector Name] = CASE WHEN datalength($q) = 0 THEN [Collector Name] ELSE '$ q'结束 只是我的一个代码审查说明(我承认我对 php 了解不多),但这段代码对我来说似乎很容易注入。其余的 PHP 代码是否有阻止 SQLi 的东西? 【参考方案1】:

检查变量的长度而不是字段的长度

代替

WHERE ([Collector Name] = '$q' OR datalength([Collector Name]) = 0)

应该是:

WHERE ([Collector Name] = '$q' OR datalength('$q') = 0)
                                             ^^^^

【讨论】:

【参考方案2】:

我不熟悉 php,但对于 sql,我认为您首先需要检查变量是否不为 null 然后使用它,也许在您的 php 代码中,如果未选择该值,您可以将值默认为 null。

SELECT
    [Customer]
   ,[Collector Name]
   ,[Bill Date]
   ,[Days Until Next Action]
   ,[Next Action]
   ,[Next Bill Date]
   ,[Billed Status]
   ,[Billed Amount]
   ,[Total Current Balance]
   ,CAST([Payment Due Date] AS DATE) AS [Payment Due Date]
   ,[Notes]
   ,[Payment Status]
   ,[Line Status]
FROM [Test_Spec_Bill]
WHERE (
('$q' IS NOT NULL
AND [Collector Name] = '$q')
OR DATALENGTH([Collector Name]) = 0
)
AND (('$date' IS NOT NULL
AND [Date Group - Filter] = '$date')
OR DATALENGTH([Date Group - Filter]) = 0
)
AND (('$val' IS NOT NULL
AND [Billed Status] = '$val')
OR DATALENGTH([Billed Status]) = 0
)
AND (('$rep' IS NOT NULL
AND [Parent Report Code] = '$rep')
OR DATALENGTH([Parent Report Code]) = 0
)
AND (('$group' IS NOT NULL
AND [Balance Group - Filter] = '$group')
OR DATALENGTH([Balance Group - Filter]) = 0
)

【讨论】:

【参考方案3】:

DATALENGTH = 0 永远不会将 NULL 值评估为零,因为对于 NULLDATALENGTH 返回 NULL。您可以在发送查询之前处理NULL 值,或者像这样使用IFNULL 简单地将NULL 案例评估为真。

 WHERE ([Collector Name] = '$q' OR datalength(IFNULL([Collector Name], 0)) = 4)
        AND ([Date Group - Filter] = '$date' OR datalength(IFNULL([Date Group - Filter], 0)) = 4)
        AND ([Billed Status] = '$val' OR datalength(IFNULL([Billed Status], 0)) = 4)
        AND ([Parent Report Code] = '$rep' OR datalength(IFNULL([Parent Report Code],0)) = 4)
        AND ([Balance Group - Filter] = '$group' OR datalength(IFNULL([Balance Group - Filter],0)) = 4)

【讨论】:

以上是关于SQL Server 查询仅在没有变量为空时才有效的主要内容,如果未能解决你的问题,请参考以下文章

Sql Server:如何仅在存在时才选择列?

仅当字段为空时才更新来自 select 语句的查询

仅当查询不为空时,才从查询写入 BigQuery 中的表

仅当特定输入为空时,如何禁用按钮?

JPA:仅当结果集不为空时才缓存查询

FluentValidation - 仅当值不为空时检查值是表达式