一.問題背景
測試環(huán)境測試SQL沒有問題粗合,但是上生產(chǎn)環(huán)境之后啸盏,sql執(zhí)行報(bào)錯(cuò)
二.現(xiàn)象
生產(chǎn)環(huán)境:點(diǎn)擊‘一鍵還款確認(rèn)’按鈕住诸,顯示‘發(fā)起還款確認(rèn)失敗’暑脆。監(jiān)控系統(tǒng)發(fā)送郵件抱錯(cuò)‘BadSqlGrammarException’维咸,
Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: In aggregated query without GROUP BY, expression #2 of SELECT list contains nonaggregated column 'malm.t.buy_back_date'; this is incompatible with sql_mode=only_full_group_by ### The error may exist in class path resource [mybatis/financial/customized/BuybackDao.xml] ### The error may involve
三.分析
查詢的SQL為:
select
sum(a.advance_amount) as advanceSumAmount,
COUNT(1) as countNum,
sum(a.expected_principal_amount) as expectedPrincipalAmount,
sum(a.expected_interest_amount) as expectedInterestAmount,
sum(a.expected_fine_amount) as expectedFineAmount,
sum(a.expected_service_amount) as expectedServiceAmount,
a.pay_date as payDate
from tb_loan_prepayment a
where a.capital_id = 2
AND a.STATUS = 5
AND a.pay_date BETWEEN '2017-10-27' AND '2017-10-27 23:59:59';
該sql在測試環(huán)境運(yùn)行時(shí)沒有報(bào)錯(cuò)的剂买,并且能夠正確地返回結(jié)果。那為什么到了生產(chǎn)環(huán)境就不能執(zhí)行呢癌蓖?原因在于兩個(gè)環(huán)境使用的SQL_Mode不同瞬哼。
sql模式定義了MySQL應(yīng)支持的SQL語法,以及應(yīng)該在數(shù)據(jù)上執(zhí)行何種確認(rèn)檢查租副。我們可以使用 select @@sql_mode; 來查看mysql使用的模式坐慰。
以下為測試環(huán)境的執(zhí)行結(jié)果(STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION)
以下為生產(chǎn)環(huán)境的執(zhí)行結(jié)果(ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION)其中,ONLY_FULL_GROUP_B
Y就是導(dǎo)致以上現(xiàn)象的問題所在用僧。其限制為:對于GROUP BY聚合操作结胀,如果在SELECT中的列赞咙,沒有在GROUP BY中出現(xiàn),那么這個(gè)SQL是不合法的糟港,因?yàn)榱胁辉贕ROUP BY從句中攀操。
四.解決:
方法1)在應(yīng)用中修改sql語法問題,添加GROUP BY條件秸抚。
方法2)將生產(chǎn)環(huán)境的sql模式同步到測試環(huán)境速和。同步以后保證兩個(gè)環(huán)境無差異,可以有效防止其他同事或其他sql限制造成該問題