为什么 `LIKE` 运算符不适用于整数列?
Why is the `LIKE` operator not working with integer columns?
我正在尝试从我的数据库中接收一些 ID,以便在我的 CAKEPHP 3.3 站点上进行自动完成搜索。但我的问题是,如果我输入确切的 ID 而不是它的一部分,它只会返回 ID。
这是我搜索数据的功能。名称变量是从输入传递的内容。
public function search()
{
if ($this->request->is('ajax'))
{
$name = $this->request->query['term'];
$resultArr = $this->Invoices->find('all', [
'conditions' => ['Invoices.id LIKE' => ($name . '%')]
]);
$resultsArr = [];
foreach ($resultArr as $result)
{
$resultsArr[] = ($result['id']);
}
$this->set('resultsArr', $resultsArr);
// This line is what handles converting your array into json
// To get this to work you must load the request handler
$this->set('_serialize', ['resultsArr']);
}
}
例如,在 table '5254' 中有一个 ID,我输入了 ID '52' 的一部分,但没有返回任何内容,但是当我输入整个 ID '5254' 时,返回了 ID .
我不确定为什么会这样,因为在我的 sql 查询中,我使用百分号表示输入内容后的任何字符。
这是我的一部分 table
SQL 输入 52 时进行调试。
object(Cake\ORM\Query) {
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'SELECT Invoices.id AS `Invoices__id`, Invoices.start_date AS `Invoices__start_date`, Invoices.close_date AS `Invoices__close_date`, Invoices.customer_id AS `Invoices__customer_id`, Invoices.invoice_to_address AS `Invoices__invoice_to_address`, Invoices.ship_to_address AS `Invoices__ship_to_address`, Invoices.customer_contact_id AS `Invoices__customer_contact_id`, Invoices.aircraft_registration_id AS `Invoices__aircraft_registration_id`, Invoices.shipping_company_id AS `Invoices__shipping_company_id`, Invoices.notes AS `Invoices__notes`, Invoices.worksheet_notes AS `Invoices__worksheet_notes`, Invoices.closed AS `Invoices__closed`, Invoices.times_printed AS `Invoices__times_printed`, Invoices.payment_due AS `Invoices__payment_due`, Invoices.GST_rate AS `Invoices__GST_rate`, Invoices.opening_notes AS `Invoices__opening_notes`, Invoices.courier_ticket AS `Invoices__courier_ticket`, Invoices.job_description AS `Invoices__job_description`, Invoices.worksheets_printed AS `Invoices__worksheets_printed`, Invoices.supervising_engineer_id AS `Invoices__supervising_engineer_id`, Invoices.job_type_id AS `Invoices__job_type_id`, Invoices.opened_by_id AS `Invoices__opened_by_id`, Invoices.assigned_to_id AS `Invoices__assigned_to_id`, Invoices.certification_required AS `Invoices__certification_required`, Invoices.currency_id AS `Invoices__currency_id`, Invoices.xero_batch_number AS `Invoices__xero_batch_number`, Invoices.xero_amount AS `Invoices__xero_amount`, Invoices.exchange_rate AS `Invoices__exchange_rate`, Invoices.payment_instructions AS `Invoices__payment_instructions`, Invoices.email AS `Invoices__email`, Invoices.inv_email AS `Invoices__inv_email` FROM invoices Invoices WHERE Invoices.id like :c0',
'params' => [
':c0' => [
'value' => '52%',
'type' => 'integer',
'placeholder' => 'c0'
]
这样试试:
'conditions' => ['Invoices.id LIKE' => '"' . $name . '%"']
id
列的类型为 INTEGER
,因此该值是这样绑定的,正如您在查询转储中看到的那样,它表示 'type' => 'integer'
。被绑定为一个整数会导致它被强制转换,你最终只会与 52
进行比较。
您可以通过告诉查询构建器将该列视为字符串类型来解决这个问题。这可以通过查询构建器 *where()
方法的第二个参数 ($types
) 完成:
$this->Invoices
->find()
->where(
['Invoices.id LIKE' => ($name . '%')],
['Invoices.id' => 'string']
);
另见
在这种情况下,您可以 "inject" 普通查询 - conditions
中具有数字索引的数组值被视为普通查询,并且不会被参数化。注意:在这种情况下必须强制转换为整数以防止 SQL 注入:
$result = $this->Invoinces->find('all' , [
'conditions' => [
'id LIKE "'.(int)$input.'%" '
]
])
->toArray();
你仍然可以在 cakephp 3 中这样做
$results = $clients->find()->select(['id','email','name','accountid','created','status'])
->Where(function (QueryExp $exp, Query $q) use ($requestData) {
$orCond = $exp->or_([
new Comparison('accountid',$requestData['search']['value'],null,'LIKE'),
new Comparison('email',$requestData['search']['value'],null,'LIKE'),
new Comparison('name',$requestData['search']['value'],null,'LIKE'),
new Comparison('created',$requestData['search']['value'],null,'LIKE'),
new Comparison('status',$requestData['search']['value'],null,'LIKE'),
]);
return $exp->add($orCond);
});
我正在尝试从我的数据库中接收一些 ID,以便在我的 CAKEPHP 3.3 站点上进行自动完成搜索。但我的问题是,如果我输入确切的 ID 而不是它的一部分,它只会返回 ID。
这是我搜索数据的功能。名称变量是从输入传递的内容。
public function search()
{
if ($this->request->is('ajax'))
{
$name = $this->request->query['term'];
$resultArr = $this->Invoices->find('all', [
'conditions' => ['Invoices.id LIKE' => ($name . '%')]
]);
$resultsArr = [];
foreach ($resultArr as $result)
{
$resultsArr[] = ($result['id']);
}
$this->set('resultsArr', $resultsArr);
// This line is what handles converting your array into json
// To get this to work you must load the request handler
$this->set('_serialize', ['resultsArr']);
}
}
例如,在 table '5254' 中有一个 ID,我输入了 ID '52' 的一部分,但没有返回任何内容,但是当我输入整个 ID '5254' 时,返回了 ID .
我不确定为什么会这样,因为在我的 sql 查询中,我使用百分号表示输入内容后的任何字符。
这是我的一部分 table
SQL 输入 52 时进行调试。
object(Cake\ORM\Query) {
'(help)' => 'This is a Query object, to get the results execute or iterate it.',
'sql' => 'SELECT Invoices.id AS `Invoices__id`, Invoices.start_date AS `Invoices__start_date`, Invoices.close_date AS `Invoices__close_date`, Invoices.customer_id AS `Invoices__customer_id`, Invoices.invoice_to_address AS `Invoices__invoice_to_address`, Invoices.ship_to_address AS `Invoices__ship_to_address`, Invoices.customer_contact_id AS `Invoices__customer_contact_id`, Invoices.aircraft_registration_id AS `Invoices__aircraft_registration_id`, Invoices.shipping_company_id AS `Invoices__shipping_company_id`, Invoices.notes AS `Invoices__notes`, Invoices.worksheet_notes AS `Invoices__worksheet_notes`, Invoices.closed AS `Invoices__closed`, Invoices.times_printed AS `Invoices__times_printed`, Invoices.payment_due AS `Invoices__payment_due`, Invoices.GST_rate AS `Invoices__GST_rate`, Invoices.opening_notes AS `Invoices__opening_notes`, Invoices.courier_ticket AS `Invoices__courier_ticket`, Invoices.job_description AS `Invoices__job_description`, Invoices.worksheets_printed AS `Invoices__worksheets_printed`, Invoices.supervising_engineer_id AS `Invoices__supervising_engineer_id`, Invoices.job_type_id AS `Invoices__job_type_id`, Invoices.opened_by_id AS `Invoices__opened_by_id`, Invoices.assigned_to_id AS `Invoices__assigned_to_id`, Invoices.certification_required AS `Invoices__certification_required`, Invoices.currency_id AS `Invoices__currency_id`, Invoices.xero_batch_number AS `Invoices__xero_batch_number`, Invoices.xero_amount AS `Invoices__xero_amount`, Invoices.exchange_rate AS `Invoices__exchange_rate`, Invoices.payment_instructions AS `Invoices__payment_instructions`, Invoices.email AS `Invoices__email`, Invoices.inv_email AS `Invoices__inv_email` FROM invoices Invoices WHERE Invoices.id like :c0',
'params' => [
':c0' => [
'value' => '52%',
'type' => 'integer',
'placeholder' => 'c0'
]
这样试试:
'conditions' => ['Invoices.id LIKE' => '"' . $name . '%"']
id
列的类型为 INTEGER
,因此该值是这样绑定的,正如您在查询转储中看到的那样,它表示 'type' => 'integer'
。被绑定为一个整数会导致它被强制转换,你最终只会与 52
进行比较。
您可以通过告诉查询构建器将该列视为字符串类型来解决这个问题。这可以通过查询构建器 *where()
方法的第二个参数 ($types
) 完成:
$this->Invoices
->find()
->where(
['Invoices.id LIKE' => ($name . '%')],
['Invoices.id' => 'string']
);
另见
在这种情况下,您可以 "inject" 普通查询 - conditions
中具有数字索引的数组值被视为普通查询,并且不会被参数化。注意:在这种情况下必须强制转换为整数以防止 SQL 注入:
$result = $this->Invoinces->find('all' , [
'conditions' => [
'id LIKE "'.(int)$input.'%" '
]
])
->toArray();
你仍然可以在 cakephp 3 中这样做
$results = $clients->find()->select(['id','email','name','accountid','created','status'])
->Where(function (QueryExp $exp, Query $q) use ($requestData) {
$orCond = $exp->or_([
new Comparison('accountid',$requestData['search']['value'],null,'LIKE'),
new Comparison('email',$requestData['search']['value'],null,'LIKE'),
new Comparison('name',$requestData['search']['value'],null,'LIKE'),
new Comparison('created',$requestData['search']['value'],null,'LIKE'),
new Comparison('status',$requestData['search']['value'],null,'LIKE'),
]);
return $exp->add($orCond);
});