我有一个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)";
答案 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)
你可以"规范化" year
与year % 100 + 2000
的{{1}}。因此,如果您搜索2018
,则条件为
year % 100 + 2000 = 2018
这将匹配:year = 18
和year = 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
)";