无法获取LIKE查询以返回记录的2位和4位年份结果

时间:2018-02-24 03:08:35

标签: php mysql

我有一个mysql数据库,其中包含"年"并且当前存储的值每年都是2位和4位数,例如" 18"和" 2018"。

我正在尝试使用LIKE返回18和2018的记录,用户选择" 2018"以HTML格式表示。

到目前为止,使用以下方法,它只返回2018年的值,而不是年份数据存储的值,就像" 18"

我可以看到它通过" 2018"值应该在URL中,并且再次,它适用于返回匹配2018的结果。

以下是完整查询:

$year = $_GET['year'];

$query = "(
SELECT * 
FROM test
WHERE ('$name' IS NULL OR '$name' = '' OR name = '$name')
AND ('$city' IS NULL OR '$city' = '' OR city = '$city') AND ('$state' IS NULL 
OR '$state' = '' OR state = '$state') AND ('$county' IS NULL OR '$county' 
= '' OR county = '$county') AND ('$year' IS NULL OR '$year' = '' 
OR year LIKE '%$year%') AND ('$month' IS NULL OR '$month' = '' OR
month = '$month')order by name)";

4 个答案:

答案 0 :(得分:1)

$year = 18;
select * from test where year LIKE '$year%'; //OUTPUTS YEAR STARTS WITH 18
select * from test where year LIKE '%$year'; //OUTPUTS YEAR ENDS WITH 18
select * from test where year LIKE '%$year%'; //OUTPUTS YEAR WITH PATTERN OF 18

答案 1 :(得分:0)

你可以"规范化" yearyear % 100 + 2000的{​​{1}}。因此,如果您搜索2018,则条件为

year % 100 + 2000 = 2018

这将匹配:year = 18year = 2018。但也year = 118

请注意,NULL将在PHP中转换为空字符串。所以像'$name' IS NULL之类的东西永远不会发生。您可以将查询简化为:

SELECT * 
FROM test
WHERE '$name'   IN ('', name)
  AND '$city'   IN ('', city)
  AND '$state'  IN ('', state)
  AND '$county' IN ('', county)
  AND '$year'   IN ('', year % 100 + 2000)
  AND '$month'  IN ('', month)
order by name

您应该使用带有占位符的预准备语句,而不是将不安全的变量注入查询字符串。

答案 2 :(得分:0)

我发现您的用户选择了2018,而您只是在2018年使用,就像您的代码所示:

$ year = $ _GET ['year'];

我建议你只将2个字符传递给$ year变量,这样就好了。

答案 3 :(得分:0)

您的数据很简单。在将数据存储到数据库之前,您应该对数据进行规范化。

准备存储

如果您希望用户在输入方面有一些自由,那就没关系了。但是,你不会在数据库上拥有这种奢侈品。要修复用户输入,可以使用函数/方法:

function normaliseYear(int $year): int
{
    if (999 < $year && $year < 10000) {
        // Year is already normalised
        return $year;
    }

    if (0 <= $year && $year < 100) {
        // Got the year within the century, assume 21. century
        return 2000 + $year;
    }

    // You can put other repairable cases here

    // Got something we can not repair
    throw new UnexpectedValueException("Unable to normalise $year as a year");
}

您在数据创建和检索时都使用此函数/方法,因此您的数据库很干净且查询保持简单(=快速)。

修复存储

因为你已经“坏了”。数据库中的数据,您需要修复它。实际上,您需要对现有数据进行相同的规范化,但幸运的是只需要一次。

UPDATE test SET year = 2000 + year WHERE year < 100;

查询

您的查询将如下所示

$year = ($year === '' || $year === null) ? null : normaliseYear((int)$_GET['year']);

// Do not forget to sanitise user input!
$month = (int)$month;
// ...

$skipName   = empty($name) ? 1 : 0;
$skipCity   = empty($city) ? 1 : 0;
$skipState  = empty($state) ? 1 : 0;
$skipCounty = empty($county) ? 1 : 0;
$skipYear   = ($year === null) ? 1 : 0;
$skipMonth  = empty($month) ? 1 : 0;

$query = "(
    SELECT * 
    FROM test
    WHERE ($skipName OR name = '$name')
      AND ($skipCity OR city = '$city')
      AND ($skipState OR state = '$state')
      AND ($skipCounty OR county = '$county')
      AND ($skipYear OR year = $year)
      AND ($skipMonth OR month = $month)
    ORDER BY name
)";