По приводению типов (postgresql)

Активист

Активист
Команда форума
C PostgreSQL не работа, но надо пару задач сделать. Подскажите, нужно безусловное приводение типов к int / decimal. Что бы не валилась ошибка, а то валится в FATAL, ибо обработчик такой:

PHP:
<?php
/**
* Класс для работы с базой данных PostgreSQL
*/
class app_db_pgsql
{
    /**
    * Аттрибут объекта содержит текущую ссылку на соединение с СУБД (connection id)
    * @var resource|null
    */
    private static $connection_id;

    /**
    * Аттрибут содержит ресурс выполненный функцией pg_execute
    * @var resource
    */
    private $_last_pg_query_resource;

    /**
    * Метод выполняет соединение с postgresql или если соединение установлено возвращает текущий линк
    * @return resource
    */
    private function connection_id()
    {
        if (!isset(self::$connection_id))
        {
            if (! (self::$connection_id = pg_connect("host=localhost dbname=db user=use password=pass")) )
            {
                trigger_error("Ошибка соединения с базой данных PostgreSQL: ".pg_last_error(), E_USER_ERROR);
            }
       
            pg_set_client_encoding(self::$connection_id, "koi8-r"); // устанавлиаем кодировку клиента в соотвествии с кодировкой сайта
        }
   
        return self::$connection_id;
    }

    /**
    * Метод подготовки SQL запроса
    * @param unknown $query
    * @return boolean
    */
    public function prepare($query)
    {
        if (! pg_prepare($this->connection_id(), "", $query) )
        {
            trigger_error("Подготовка SQL запроса {$query} завершилось неудачно: ".pg_last_error($this->connection_id()), E_USER_ERROR);
        }
   
        return $this;
    }

    /**
    * Выполняем подготовленный SQL запрос
    * @param array $params
    * @return app_db_pgsql
    */
    public function execute(array $params = array())
    {
        if (! ($this->_last_pg_query_resource = pg_execute($this->connection_id(), "", $params)) )
        {
            trigger_error("Выполнение ранее подгтовленного запроса произошло с ошибкой: ".pg_last_error($this->connection_id()), E_USER_ERROR);
        }
   
        return $this;
    }

    /**
    * Получаем строку
    * @return array
    */
    public function fetch_row()
    {
        return pg_fetch_row($this->_last_pg_query_resource);
    }

    /**
    * Получаем строку (ассоциативный массив)
    * @return array
    */
    public function fetch_assoc()
    {
        return pg_fetch_assoc($this->_last_pg_query_resource);
    }


    /**
    * Выполняет SQL без предподготовки, но с параметрами
    * @param string $query
    * @param array $params
    * @return app_db_pgsql
    */
    public function query_params($query, array $params = array())
    {
        if (! ($this->_last_pg_query_resource = pg_query_params($this->connection_id(), $query, $params)) )
        {
            trigger_error("Выполнение запроса c параметрами произошло с ошибкой: ".pg_last_error($this->connection_id()), E_USER_ERROR);
        }
   
        return $this;
    }

    /**
    * Возвращает количество затронутых строк
    * @return number
    */
    public function num_rows()
    {
        return pg_num_rows($this->_last_pg_query_resource);
    }
}
Пробовал собственно так:
PHP:
public function getTwByCode($tw_code)
    {
        $pg = new app_db_pgsql();
        $pg->query_params("select * from type_of_work where tw_code = cast($1 as int8)", array($tw_code));
       
        if ($pg->num_rows() === 1)
        {
                return $pg->fetch_assoc();
        }
       return false;
    }
Валится с ошибкой , в случае плохого INT'а:
Код:
Warning: pg_query_params() [function.pg-query-params]: Query failed: ОШИБКА: неверное значение для целого числа: "a" in /var/www/x.web.local/httpdocs/x/app/db/pgsql.php on line 95

Fatal error: Выполнение запроса c параметрами произошло с ошибкой: ОШИБКА: неверное значение для целого числа: "a" in /var/www/x.web.local/httpdocs/x/app/db/pgsql.php on line 97
На PHP приводить к unsigned int не вариант (поскольку максимального значения для PHP-шного INT меньше чем bigint PostreSQL)
 
Последнее редактирование:

Активист

Активист
Команда форума
Вот в чем проблема:

PHP:
root@linux-debian-1:~# cat test.php
<?php
echo (9223372036854775806 > 0), ",", (int)9223372036854775806, "\n";
root@linux-debian-1:~# php ./test.php
1,0
root@linux-debian-1:~#
is_number не подойдет, ибо:
Код:
Warning: pg_query_params() [function.pg-query-params]: Query failed: ОШИБКА: значение "9223372036854775808" вне диапазона для типа bigint in /var/www/x.web.local/httpdocs/x/app/db/pgsql.php on line 95

Fatal error: Выполнение запроса c параметрами произошло с ошибкой: ОШИБКА: значение "9223372036854775808" вне диапазона для типа bigint in /var/www/x.web.local/httpdocs/x/app/db/pgsql.php on line 97
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Подскажите, нужно безусловное приводение типов к int / decimal. Что бы не валилась ошибка...
А к какому числу это безусловное приведение должно приводить букву "a" или число за пределами диапазона int8?
 

Sad Spirit

мизантроп (Старожил PHPClub)
Команда форума
Вот кстати придумалось Элегантное Решение:
Код:
create function shit_to_integer(incoming_shit text, default_shit int8 default null)
returns int8
as $$
begin
  begin
    return incoming_shit::int8;
  exception
    when numeric_value_out_of_range or invalid_text_representation then
      return default_shit;
  end;
end;
$$ language plpgsql immutable called on null input security definer;
Соответственно shit_to_integer('a') вернёт нам null, shit_to_integer('a', 666) вернёт 666.
 

Активист

Активист
Команда форума
А к какому числу это безусловное приведение должно приводить букву "a" или число за пределами диапазона int8?
Есть два варианта:
1. Передано не число;
2. Передано число за приделами.

MySQL приводит к пустоте (но не NULL), насколько я знаю. В MySQL проверка входных данных и генерация ошибок , подобных PG - это strict mode, который отключается.

1 - ое еще теститься на валидацию;
2 - ое уже нельзя проверить, в PHP.

За функцию спасибо)
 
Последнее редактирование:
Сверху