bindValue и сортировка

friday

Новичок
bindValue и сортировка

Имеется система, написанная на PHP+PgSQL. Для обращений к БД используется след. схема:

каждый запрос лежит в отдельном файле, текст запроса не модифицируется: параметры передаются посредством PDOStatement::bindVariable().

Потребовалось модифицировать некоторые выборки - ввести сортировку по столбцам, выбранным юзером. Каким образом эти столбцы передать постгресу? bindVariable() здесь, понятное дело, не катит, т.к. передается строка.

Система довольно развесистая, и не хотелось бы много переписывать, т.к. это чревато неприятными последствиями. Т.ч. вариант с модификацией SQL на лету отпадает.

debian etch
postgresql-8.3 (etch-backports)
php-5.2.0
 

spiverg

Новичок
bindVariable() здесь, понятное дело, не катит
bindValue() вполне катит через небольшие костыли)
есть два варианта
1. Легкий, но не очень удобный, передаешь вместо имени "столбца" его числовой идентификатор (Each expression can be the name or ordinal number of an output column)
выглядит это примерно так:
Код:
$sth = $pdo->prepare('SELECT col_1, col_2 FROM example ORDER BY ?');
$sth->bindValue(1, 1, PDO::PARAM_INT);
$sth->execute();
в данном примере произойдет сортировка по col_1
2. Наверное понятно что вариант 1 не очень удобен везде эти непонятные порядковые номера, опять же что делать если нужно сортировать по нескольким "столбцам", поэтому есть вариант более сложный, но в тоже время более удобный, можно найти/написать хранимую процедуру которая будет вместо переданной строки содержащей имя "столбца" подставлять его порядковый номер,
выглядит это примерно так:
Код:
$sth = $pdo->prepare('SELECT col_1, col_2 FROM example ORDER BY YOUR_PROC(?)');
$sth->bindValue(1, 'col_1', PDO::PARAM_STR);
$sth->execute();
 

friday

Новичок
Первый вариант я пробовал. Не прокатывает. Т.е. если я пишу номер столбца в самом запросе, все работает нормально, а если передаю через bindValue(), он просто-напросто игнорируется. Похоже, что он сортирует по _значению_ передаваемого числа. А оно, понятно, для всех строк одно.

-~{}~ 17.07.08 11:11:

Подозреваю, что во втором варианте будет тоже самое. Впрочем, попробую.
 

spiverg

Новичок
только что проверил у себя все отлично работает, покажи код
 

friday

Новичок
SELECT id, title, description AS descr
FROM banners
WHERE campaign_id=:id
ORDER BY :col;

. . .

$sth->prepare(file_get_contents('sql/banners_list'));
$sth->bindValue(':id', $id);
$sth->bindValue(':col', 2);
 

spiverg

Новичок
попробуй изменить
PHP:
$sth->bindValue(':col', 2);
на
PHP:
$sth->bindValue(':col', 2, PDO::PARAM_INT);
 

friday

Новичок
Запрос в предыдущем посте.
Попробую, спасибо.

-~{}~ 17.07.08 14:25:

Автор оригинала: spiverg
попробуй изменить
PHP:
$sth->bindValue(':col', 2);
на
PHP:
$sth->bindValue(':col', 2, PDO::PARAM_INT);
Попробовал. Не помогло.
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Автор оригинала: friday
каждый запрос лежит в отдельном файле, текст запроса не модифицируется: параметры передаются посредством PDOStatement::bindVariable().

Потребовалось модифицировать некоторые выборки - ввести сортировку по столбцам, выбранным юзером. Каким образом эти столбцы передать постгресу? bindVariable() здесь, понятное дело, не катит, т.к. передается строка.
Тащемта здесь наблюдается некоторое противоречие в постановке задачи: требуется выполнять запросы с разным текстом (а с точки зрения СУБД это именно так), но при этом не менять текст запроса.

В связи с такой постановкой предлагаются два интересных решения:
1) сгенерировать новые файлы с запросами по числу возможных сортировок
2) написать процидурки по числу имеющихся файлов, которые будут принимать параметры запроса и поля для сортировки. Потом внутри процидурки будет генериться искомый запрос и выполняться через EXECUTE.
 
Сверху