Включить динамический c индекс массива в Sql запрос - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть запрос вроде этого -

$result4 = mysqli_query($connection3, "UPDATE Users SET SortedOrder= (((SortedOrder+$currentTokenArray[2])+(SortedOrder+$currentTokenArray[3]))/2) where WaitLessNumber=$partner_id AND TokenNumber in (".implode(',',$sequenceArray).")");

Я хочу сделать индекс $currentTokenArray[2] и $currentTokenArray[3] dynamici c как $currentTokenArray[$i+2] и $currentTokenArray[$i+3] соответственно где $i будет принимать последовательные значения, такие как 1,2,3,4,5, ...

Так что в первой итерации он будет вычислять

SortedOrder= (((SortedOrder+$currentTokenArray[2])+(SortedOrder+$currentTokenArray[3]))/2)

, во второй итерации он будет вычислить

SortedOrder= (((SortedOrder+$currentTokenArray[3])+(SortedOrder+$currentTokenArray[4]))/2)

и т. д.

Есть ли способ сделать это?

Примечание: последовательная последовательность 1,2,3,4, ... также доступно в столбце TokenNumber таблицы, как указано в приведенном выше запросе.

1 Ответ

0 голосов
/ 21 февраля 2020

Это очень грубая схема достижения желаемого результата. Когда я написал это, я сделал много предположений, которые могут оказаться ошибочными. Код может потребовать настройки.

Например, вы должны использовать реальные данные для подключения. SortedOrder, currentTokenArray, partner_id и $sequenceArray переменные должны откуда-то приходить.

Также самое большое значение currentTokenArray - это массив фиксированной длины, глобально. Код должен быть настроен для динамического c currentTokenArray.

Я пытался разместить столько комментариев, сколько мог.

<?php

// Update. A better error reporting setup

// Turn on displaying errors
ini_set('display_errors', 1);
// Set reporting to everything.
ini_set('error_reporting', E_ALL);
// Make Mysqli trow exceptions instead of warnings.
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

/** I assume SortedOrder has to come from somewhere also, for testing purposes it's set to 0.
    However this is not really correct, SortedOrder can be defined anywhere,
    probably somewhere at global scope, but that is an assumption.
    The functions are not really needed, but I will leave them because it might be easier to understand
    where arrays come from and what sizes they are.
    Also you can always replace the redundant generation with some actual code for getting values
*/
function getToken() {
  $token = array(); // Creating example array for holding the data

  // Filling the array with some data
  for($i=0; $i<10; ++$i) {
    array_push($token, $i); //Here we add an element to the end of the array.
  }
  return $token;
}
function getSequenceArr() {
  $sequenceArray = array(); // Creating example array for holding the data

  // Filling the array with some data
  for($i = 30; $i < 40; ++$i) {
    array_push($sequenceArray, $i); //Here we add an element to the end of the array
  }
  return $sequenceArray;
}

$SortedOrder = 0;

/** In reality this should also be somewhere else. At the include file, or even the config file.
    For testing purposes.
*/
// Connect to database, use actual data for host, username, password and database name
$conn = mysqli_connect("127.0.0.1", "username", "pass", "database");

// I assume token has to come from somewhere
$currentTokenArray = getToken();

// sequenceArray has also to come from somewhere.
$sequenceArray = getSequenceArr();

// We only have to implode array once. Result is a string.
$imploded = implode(", ", $currentTokenArray);
echo "$imploded</br>";

// partner_id comes from somewhere, for example purposes it is set to one. I am assuming partner_id is number
$partner_id = 1;

// Make placeholders for numbers
$in    = str_repeat('?,', count($currentTokenArray) - 1) . '?';
$types = str_repeat('d', count($currentTokenArray));
// This is where param binding comes in. We put ? to places where binding will occur. Explanation sucks, but I suck at good explaining.
// Docs shed more light on it. As it was pointed out we only need to do it once
$query = "UPDATE Users SET SortedOrder = ? where WaitLessNumber = ? AND TokenNumber IN ($in)";

$stmt = $conn->prepare($query); // Preparing the query

// We can't iterate using foreach as we have to stop before the last element in the array.
for($i = 0; $i < count($currentTokenArray)-2; $i++) {
  $token = $currentTokenArray[$i]; // Get current token. I am assuming here token is a number as it is used in calculations.
  $SortedOrder = ((($SortedOrder+$currentTokenArray[$i])+($SortedOrder+$currentTokenArray[$i+1]))/2);
  echo "$SortedOrder</br>";

  // Binding values. Operator ... is arcument unpacking
  $stmt->bind_param('dd'.$types, $SortedOrder, $partner_id, ...$currentTokenArray);
  $stmt->execute();
  printf("%d Rows updated.</br>", $stmt->affected_rows); // Check how much rows were updated;
}

$stmt->close(); // Close statement

$conn->close(); // Close connection

Реализация хранения SortedOrder отстой немного также. Значение существует только во время работы скрипта. Чтобы сохранить его, когда скрипт не запущен, но это самый простой способ сделать это.

Если вы хотите сохранить значение SortedOrder между двумя запущенными скриптами, сохраните его в базе данных или даже в текстовом файле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...