23 private const KEY_FIELDS_SEPARATOR =
'#kvA3[56U?OWz16l#';
34 $length =
count($list);
41 $partsCount = ceil($length / $limit);
42 for ($index = 0; $index < $partsCount; $index++)
44 $result[$index] = array_slice($list, $limit * $index, $limit);
58 $conHelper = Application::getConnection()->getSqlHelper();
59 foreach($values as $index => $value)
61 $values[$index] = $conHelper->forSql($value);
64 return "'" . implode(
"', '", $values) .
"'";
76 $ids = []; $sets = [];
79 if (!isset($item[
'ID']) || !$item[
'ID'])
84 $id = (int) $item[
'ID'];
92 foreach ($item as
$key => $value)
94 if (!isset($sets[
$key]))
99 $sets[
$key][$id] = $value;
108 $conHelper = Application::getConnection()->getSqlHelper();
109 $ids = implode(
',', $ids);
111 foreach ($sets as
$key => $values)
114 foreach ($values as $id => $value)
116 $value = $conHelper->forSql($value);
117 $stringSet .=
"\nWHEN ID = $id THEN '$value'";
119 $stringSet =
"\n$key = CASE $stringSet ELSE $key END";
120 $stringSets[] = $stringSet;
122 $stringSets = implode(
', ', $stringSets) .
"\n";
125 $sql =
"UPDATE $tableName SET $stringSets WHERE ID in ($ids)";
126 Application::getConnection()->query($sql);
142 array $onDuplicateUpdateFields = [],
143 array $primaryFields = []
146 $columnNames = self::getFieldNames(
$fields);
147 if (
count($columnNames) == 0)
152 $sqlHelper = Application::getConnection()->getSqlHelper();
154 if (!empty($onDuplicateUpdateFields))
156 $sqlUpdateFields = [];
157 foreach ($onDuplicateUpdateFields as $field)
159 if (is_array($field))
161 $sqlUpdateFields[$field[
'NAME']] = $field[
'VALUE'];
166 'case when ?v is null then ?#.?# else ?v end',
174 $fields = self::getUniqueRowsByPrimaryFields(
$fields, $primaryFields);
176 $sql = self::prepareMergeValues($tableName, $primaryFields,
$fields, $sqlUpdateFields);
180 $columnNamesString = implode(
", ", $columnNames);
184 [$columnNamesString, $valuesString] = $sqlHelper->prepareInsert($tableName, $row);
185 $valuesStrings[] = $valuesString;
187 $dataListString = implode(
'),(', $valuesStrings);
188 $sql = $sqlHelper->getInsertIgnore($tableName,
"($columnNamesString)",
" VALUES($dataListString)");
191 Application::getConnection()->query($sql);
198 foreach(
$rows as $row)
200 $primaryValues = array_intersect_key($row, array_flip($primaryFields));
201 $key = implode(self::KEY_FIELDS_SEPARATOR, $primaryValues);
202 $unique[
$key] = $row;
205 return array_values($unique);
212 return array_keys(
$items);
230 private static function prepareMergeValues(
string $tableName,
array $primaryFields,
array $insertRows,
array $updateFields = []): string
232 $sqlHelper = Application::getConnection()->getSqlHelper();
233 $insertColumns = array_keys($insertRows[array_key_first($insertRows)] ?? []);
234 $insertValuesStrings = [];
235 foreach ($insertRows as $row)
237 [, $rowValues] = $sqlHelper->prepareInsert($tableName, $row);
238 $insertValuesStrings[] = $rowValues;
241 if (empty($updateFields))
243 $notPrimaryFields = array_diff($insertColumns, $primaryFields);
244 if (empty($notPrimaryFields))
246 trigger_error(
"Only primary fields to update, use getInsertIgnore() or specify fields", E_USER_WARNING);
248 $updateFields = $notPrimaryFields;
251 $compatibleUpdateFields = [];
253 foreach ($updateFields as
$key => $value)
255 if (is_numeric(
$key) && is_string($value))
257 $compatibleUpdateFields[
$value] =
new SqlExpression(
'?v', $value);
265 $insertValueString =
'values (' . implode(
'),(', $insertValuesStrings) .
')';
267 return $sqlHelper->prepareMergeSelect($tableName, $primaryFields, $insertColumns, $insertValueString, $compatibleUpdateFields);