🍑
[PHP×SQL]where句のinを指定した長さ以内で分割する
where句のinを指定した長さ以内で分割するサンプルコードです
クエリ長が長すぎて、エラーが発生し処理を実行できなくなる場合や、データベースへの負荷を分散したい場合などに
コード
where句のinを分割するパーツのみ書きます
<?php
// メモリ設定: 環境に合わせて適宜変更
ini_set('memory_limit','256M');
// where句のin
$inSql='123,4567,8910,11,121314,15,16171819,20,21,222324,2526272829,3031,32,33343536,3738,3940,41,424344,4546,47,484950,51,52,5354555657,585960,61';
// where句のin最大長(単位: バイト)
$maxLen=35;
$inSqlLen=strlen($inSql);
echo $inSqlLen.PHP_EOL;
$arr=[];
$i=0;
while(true){
$inSqlToLast=substr($inSql,$i);
if(strlen($inSqlToLast)<= $maxLen){
array_push($arr,$inSqlToLast);
break;
}else{
// where句のinをi番目から最大長分切り取り
$inSqlAfter=substr($inSql,$i,$maxLen);
// 切り取リ結果のいちばん後ろの「,」の位置を取得
$place=strrpos($inSqlAfter,',');
// 切り取り結果の先頭から「,」のひとつ前の文字までを取得
$result=substr($inSqlAfter,0,$place);
array_push($arr,$result);
}
// 先頭の 「,」をスキップするため、+1する
$i=$i+$place+1;
}
// 結果確認
var_dump($arr);
ポイント
substrでまず最大長分切り出した後、strrposでいちばん後ろの「,」の位置を求めること
実際の用途
BigQueryで実行したクエリが1024KBを超えてエラーになってしまったため、その対処として上記処理を書きました
実際に発生したエラー
{
"error": {
"code": 400,
"message": "The query is too large. The maximum standard SQL query length is 1024.00K characters, including comments and white space characters.",
"errors": [
{
"message": "The query is too large. The maximum standard SQL query length is 1024.00K characters, including comments and white space characters.",
"domain": "global",
"reason": "invalid"
}
],
"status": "INVALID_ARGUMENT"
}
}
Discussion