Я выполняю SQL-запрос с Yii2 DAO.
$db->createCommand("DO $$
DECLARE
rec RECORD;
pos INT := 0;
BEGIN
FOR rec IN (SELECT * FROM table1 WHERE "type" = :t LOOP
UPDATE table1 SET position = pos WHERE id = rec.id;
pos := pos + 2;
END LOOP;
END;
$$ language 'plpgsql'
", [':t' => 0])->execute();
Но это не с ошибкой:
SQLSTATE[42P18]: Indeterminate datatype: 7 ERROR: could not determine data type of parameter $1
type
колонка имеет INT
тип. Я пытался установить тип параметра явно с [':t' => [0, \PDO::PARAM_INT]]
, Но ошибка все еще здесь. Если я объединяю значение прямо в строку SQL, это работает, но это не решение. :t
только один параметр в этом запросе.
Другие простые SQL-запросы работают успешно. Эта проблема существует только для запросов с процедурами. Если я запускаю этот запрос из DataGrip, он работает. Но в PHP это не удается.
Почему это не работает и как я могу связать параметры для таких запросов?
если ты создать актуальную функцию и позвоните, вы можете пройти ценности в качестве параметров.
Но пока вы выполняете DO
заявление, тело функции (заключено в кавычки $$
в вашем примере) это просто строковый литерал. Нет передачи параметров и ничего не возвращено. Вы должны были бы сцеплять значения в виде строк в коде plpgsql.
Но вам тоже не нужно. Используйте простой подготовленное заявление вместо. Гораздо дешевле, чем в любом случае
UPDATE table1 t
SET position = t1.pos
FROM (
SELECT id, (row_number() OVER () - 1) * 2 AS pos
FROM table1
WHERE "type" = :t
) t1
WHERE t.id = t1.id
Теперь просто передать значение параметра.
В сторону: результат является произвольным, если вы не добавите ORDER BY
к OVER
пункт. Эта слабость тоже в твоем оригинале.
Связанные с:
Других решений пока нет …