使用准备好的语句时如何将参数传递给 "WHERE IN" 查询?
How to pass parameters to "WHERE IN" query when using a prepared statement?
几天来我一直在尝试解决这个问题,但似乎找不到解决方案。
我正在使用 Laravel 并尝试执行一个 Mysql 查询,该查询具有多个 "WHERE" 和 "WHERE IN" 子句,但如果单个 "WHERE IN"包含多个值,查询失败,因为它在整个参数周围添加了引号。
我将参数作为字符串传递。如果它包含一个值它工作正常但当它包含多个时失败。
$arrival_location = "PALMA"; // WORKS
$arrival_location = "PALMA, BEIJING"; // FAILS
我试过几种不同的方式传递参数,但都无济于事。
北京帕尔马
'PALMA'、'BEIJING'
"'PALMA', 'BEIJING'"
这里是查询...
$travel_data = DB::select(DB::raw('SELECT sd.FlightNumber, c1.Country as ArrivalCountry, c1.CityName as ArrivalCity, c2.Country as DepartureCountry, c2.CityName as DepartureCity, a.AirlineName, c1.LatDeg, c1.LonDeg, tp.emergency_name, tp.emergency_relation, tp.emergency_address_line_1, tp.emergency_address_line_2,tp.emergency_city, tp.emergency_country, tp.emergency_post_code, tp.emergency_landline_number, tp.emergency_mobile_number
FROM (SELECT max(PnrBfVersion) as pnrversion, TransactionsID, RecordLocator as recordlocator FROM transactions GROUP BY RecordLocator) as max
JOIN transactions t
ON max.pnrversion = t.PnrBfVersion AND max.recordlocator = t.RecordLocator
LEFT JOIN transaction_details td
ON t.TransactionsID = td.TransactionsID
LEFT JOIN segment_details sd
ON td.TransactionDetailsID = sd.TransactionDetailsID
LEFT JOIN cities c1
ON sd.ArrivalCityCode = c1.CityCode
LEFT JOIN cities c2
ON sd.DepartureCityCode = c2.CityCode
LEFT JOIN airlines a
ON sd.CarrierCode = a.AirlineCode
JOIN traveller_profiles tp
ON td.TravellerID = tp.id
WHERE TravellerID IN (SELECT id FROM traveller_profiles WHERE assigned_manager = ?)
AND TravelType = "10" AND transactionStatus = "T" # Air only and Ticketed data only
AND ArrivalInfo < ?
AND (tp.passenger_first_name LIKE ? OR tp.passenger_last_name LIKE ? OR c1.CityName IN (?) OR c1.Country IN (?) OR c2.CityName IN (?) OR c2.Country IN (?) OR FlightNumber IN (?) OR AirlineName IN (?))'),
array($user_id,
$to_date,
$search_query."%",
$search_query."%",
$arrival_location,
$arrival_country,
$departure_location,
$departure_country,
$flight_number,
$supplier));
检查 MySQL 日志时,我可以看到它在整个参数周围添加了引号。
AND (tp.passenger_first_name LIKE 'placeholder%' OR tp.passenger_last_name LIKE 'placeholder%' OR c1.CityName IN ('PALMA, BEIJING CAPITAL') OR c1.Country IN ('') OR c2.CityName IN ('') OR c2.Country IN ('') OR FlightNumber IN ('') OR AirlineName IN (''))
添加我自己的引号时,它会在查询中添加斜杠...
AND (tp.passenger_first_name LIKE 'placeholder%' OR tp.passenger_last_name LIKE 'placeholder%' OR c1.CityName IN ('\'PALMA\', \'MALTA\'') OR c1.Country IN ('') OR c2.CityName IN ('') OR c2.Country IN ('') OR FlightNumber IN ('') OR AirlineName IN (''))
您不能传入单个参数并使其表示 SQL 语句中的列表。对于此查询,您可以替换:
c1.CityName IN (?)
与:
find_in_set(c1.CityName, ?) > 0
在某些情况下,这不是一个好主意,因为它会阻止索引的使用。在您的查询中,此 where
子句不太可能使用索引。
我认为你的查询是错误的。什么是 DB::select(DB::raw ??
我从未见过 DB::select 用于 laravel。我通常会这样做:
DB::table('table')
->join('another_table', 'table.id', '=', 'another_table.another_id')
->join('yet_another_table', 'table.id', '=', 'yet_another_table.yet_another_id')
->select('table.col', 'another_table.col', 'yet_another_table.col')
->get();
您可以将变量(不带引号)传递给您的连接语句。
这里有一些文档:
几天来我一直在尝试解决这个问题,但似乎找不到解决方案。
我正在使用 Laravel 并尝试执行一个 Mysql 查询,该查询具有多个 "WHERE" 和 "WHERE IN" 子句,但如果单个 "WHERE IN"包含多个值,查询失败,因为它在整个参数周围添加了引号。
我将参数作为字符串传递。如果它包含一个值它工作正常但当它包含多个时失败。
$arrival_location = "PALMA"; // WORKS
$arrival_location = "PALMA, BEIJING"; // FAILS
我试过几种不同的方式传递参数,但都无济于事。
北京帕尔马
'PALMA'、'BEIJING'
"'PALMA', 'BEIJING'"
这里是查询...
$travel_data = DB::select(DB::raw('SELECT sd.FlightNumber, c1.Country as ArrivalCountry, c1.CityName as ArrivalCity, c2.Country as DepartureCountry, c2.CityName as DepartureCity, a.AirlineName, c1.LatDeg, c1.LonDeg, tp.emergency_name, tp.emergency_relation, tp.emergency_address_line_1, tp.emergency_address_line_2,tp.emergency_city, tp.emergency_country, tp.emergency_post_code, tp.emergency_landline_number, tp.emergency_mobile_number
FROM (SELECT max(PnrBfVersion) as pnrversion, TransactionsID, RecordLocator as recordlocator FROM transactions GROUP BY RecordLocator) as max
JOIN transactions t
ON max.pnrversion = t.PnrBfVersion AND max.recordlocator = t.RecordLocator
LEFT JOIN transaction_details td
ON t.TransactionsID = td.TransactionsID
LEFT JOIN segment_details sd
ON td.TransactionDetailsID = sd.TransactionDetailsID
LEFT JOIN cities c1
ON sd.ArrivalCityCode = c1.CityCode
LEFT JOIN cities c2
ON sd.DepartureCityCode = c2.CityCode
LEFT JOIN airlines a
ON sd.CarrierCode = a.AirlineCode
JOIN traveller_profiles tp
ON td.TravellerID = tp.id
WHERE TravellerID IN (SELECT id FROM traveller_profiles WHERE assigned_manager = ?)
AND TravelType = "10" AND transactionStatus = "T" # Air only and Ticketed data only
AND ArrivalInfo < ?
AND (tp.passenger_first_name LIKE ? OR tp.passenger_last_name LIKE ? OR c1.CityName IN (?) OR c1.Country IN (?) OR c2.CityName IN (?) OR c2.Country IN (?) OR FlightNumber IN (?) OR AirlineName IN (?))'),
array($user_id,
$to_date,
$search_query."%",
$search_query."%",
$arrival_location,
$arrival_country,
$departure_location,
$departure_country,
$flight_number,
$supplier));
检查 MySQL 日志时,我可以看到它在整个参数周围添加了引号。
AND (tp.passenger_first_name LIKE 'placeholder%' OR tp.passenger_last_name LIKE 'placeholder%' OR c1.CityName IN ('PALMA, BEIJING CAPITAL') OR c1.Country IN ('') OR c2.CityName IN ('') OR c2.Country IN ('') OR FlightNumber IN ('') OR AirlineName IN (''))
添加我自己的引号时,它会在查询中添加斜杠...
AND (tp.passenger_first_name LIKE 'placeholder%' OR tp.passenger_last_name LIKE 'placeholder%' OR c1.CityName IN ('\'PALMA\', \'MALTA\'') OR c1.Country IN ('') OR c2.CityName IN ('') OR c2.Country IN ('') OR FlightNumber IN ('') OR AirlineName IN (''))
您不能传入单个参数并使其表示 SQL 语句中的列表。对于此查询,您可以替换:
c1.CityName IN (?)
与:
find_in_set(c1.CityName, ?) > 0
在某些情况下,这不是一个好主意,因为它会阻止索引的使用。在您的查询中,此 where
子句不太可能使用索引。
我认为你的查询是错误的。什么是 DB::select(DB::raw ??
我从未见过 DB::select 用于 laravel。我通常会这样做:
DB::table('table')
->join('another_table', 'table.id', '=', 'another_table.another_id')
->join('yet_another_table', 'table.id', '=', 'yet_another_table.yet_another_id')
->select('table.col', 'another_table.col', 'yet_another_table.col')
->get();
您可以将变量(不带引号)传递给您的连接语句。
这里有一些文档: