我正在使用 Case for SQL select 查询并希望动态计算价格
I am using Case for SQL select query and want to calculate price dynamically
我的控制器代码
$nicepay_commission = Configure::read('nicepay_commission');
$paypal_commission = Configure::read('paypal_commission');
$getQuery = $this->OrderProduct
->find('all', [
'contain' => [
'Orders' => ['PaymentMethods'],
'Products' => ['ProductType']
]
])
->distinct('Products.id')
->select([
'product_name' => 'MAX(Products.product_name)',
'count' => 'SUM(OrderProduct.qty)',
'actual_rate' => 'SUM(OrderProduct.actual_rate)',
'revenue_based_actual_rate' => '(
SUM(
CASE
WHEN PaymentMethods.payment_gateway = \'nicepay\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*"'.$nicepay_commission.'")/100))
WHEN PaymentMethods.payment_gateway = \'paypal\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*"'.$paypal_commission.'")/100))
ELSE (OrderProduct.actual_rate)
END
)
)'
])
->where($conditions);
但是发生了一些错误,我找不到如何管理它。
我的错误日志看起来像
2020-08-20 07:56:56 Error: [PDOException] SQLSTATE[42S22]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name '2'.
如果我静态使用这些值则没有错误
$getQuery = $this->OrderProduct
->find('all', [
'contain' => [
'Orders' => ['PaymentMethods'],
'Products' => ['ProductType']
]
])
->distinct('Products.id')
->select([
'product_name' => 'MAX(Products.product_name)',
'count' => 'SUM(OrderProduct.qty)',
'actual_rate' => 'SUM(OrderProduct.actual_rate)',
'revenue_based_actual_rate' => '(
SUM(
CASE
WHEN PaymentMethods.payment_gateway = \'nicepay\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*2)/100))
WHEN PaymentMethods.payment_gateway = \'paypal\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*1)/100))
ELSE (OrderProduct.actual_rate)
END
)
)'
])
->where($conditions);
首先,如果可以避免,绝不 将日期直接插入 SQL 片段中,即使您认为它们可能来自安全来源!
也就是说,查看生成的 SQL 查询(如果您尚未使用 Debug Kit,您应该安装它),您将值括在双引号中,即生成的 SQL 看起来像:
OrderProduct.actual_rate * "2"
在 ISO SQL 中表示 2
将用作标识符。
删除引号将解决问题,但您仍在将动态数据注入 SQL 字符串,应尽可能避免这种情况,因此您应该更进一步并绑定值,为了减少创建 SQL 注入漏洞的机会:
// ...
->select([
'product_name' => 'MAX(Products.product_name)',
'count' => 'SUM(OrderProduct.qty)',
'actual_rate' => 'SUM(OrderProduct.actual_rate)',
'revenue_based_actual_rate' => '(
SUM(
CASE
WHEN PaymentMethods.payment_gateway = \'nicepay\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate * :nicepayCommission)/100))
WHEN PaymentMethods.payment_gateway = \'paypal\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate * :paypalCommission)/100))
ELSE (OrderProduct.actual_rate)
END
)
)'
])
->bind(':nicepayCommission', $nicepay_commission, 'integer')
->bind(':paypalCommission', $paypal_commission, 'integer')
// ...
另见
我的控制器代码
$nicepay_commission = Configure::read('nicepay_commission');
$paypal_commission = Configure::read('paypal_commission');
$getQuery = $this->OrderProduct
->find('all', [
'contain' => [
'Orders' => ['PaymentMethods'],
'Products' => ['ProductType']
]
])
->distinct('Products.id')
->select([
'product_name' => 'MAX(Products.product_name)',
'count' => 'SUM(OrderProduct.qty)',
'actual_rate' => 'SUM(OrderProduct.actual_rate)',
'revenue_based_actual_rate' => '(
SUM(
CASE
WHEN PaymentMethods.payment_gateway = \'nicepay\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*"'.$nicepay_commission.'")/100))
WHEN PaymentMethods.payment_gateway = \'paypal\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*"'.$paypal_commission.'")/100))
ELSE (OrderProduct.actual_rate)
END
)
)'
])
->where($conditions);
但是发生了一些错误,我找不到如何管理它。
我的错误日志看起来像
2020-08-20 07:56:56 Error: [PDOException] SQLSTATE[42S22]: [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name '2'.
如果我静态使用这些值则没有错误
$getQuery = $this->OrderProduct
->find('all', [
'contain' => [
'Orders' => ['PaymentMethods'],
'Products' => ['ProductType']
]
])
->distinct('Products.id')
->select([
'product_name' => 'MAX(Products.product_name)',
'count' => 'SUM(OrderProduct.qty)',
'actual_rate' => 'SUM(OrderProduct.actual_rate)',
'revenue_based_actual_rate' => '(
SUM(
CASE
WHEN PaymentMethods.payment_gateway = \'nicepay\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*2)/100))
WHEN PaymentMethods.payment_gateway = \'paypal\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate*1)/100))
ELSE (OrderProduct.actual_rate)
END
)
)'
])
->where($conditions);
首先,如果可以避免,绝不 将日期直接插入 SQL 片段中,即使您认为它们可能来自安全来源!
也就是说,查看生成的 SQL 查询(如果您尚未使用 Debug Kit,您应该安装它),您将值括在双引号中,即生成的 SQL 看起来像:
OrderProduct.actual_rate * "2"
在 ISO SQL 中表示 2
将用作标识符。
删除引号将解决问题,但您仍在将动态数据注入 SQL 字符串,应尽可能避免这种情况,因此您应该更进一步并绑定值,为了减少创建 SQL 注入漏洞的机会:
// ...
->select([
'product_name' => 'MAX(Products.product_name)',
'count' => 'SUM(OrderProduct.qty)',
'actual_rate' => 'SUM(OrderProduct.actual_rate)',
'revenue_based_actual_rate' => '(
SUM(
CASE
WHEN PaymentMethods.payment_gateway = \'nicepay\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate * :nicepayCommission)/100))
WHEN PaymentMethods.payment_gateway = \'paypal\'
THEN (OrderProduct.actual_rate-((OrderProduct.actual_rate * :paypalCommission)/100))
ELSE (OrderProduct.actual_rate)
END
)
)'
])
->bind(':nicepayCommission', $nicepay_commission, 'integer')
->bind(':paypalCommission', $paypal_commission, 'integer')
// ...
另见