Как преобразовать пустой в ноль в PostgreSQL?

У меня есть несколько столбцов типа int, но значение пусто. Поэтому я хочу преобразовать пустой в ноль, когда я вставляю в базу данных. Я использую код:

function toDB($string) {
    if ($string == '' || $string == "''") {
        return 'null';
    } else {
        return "'$string'";
    }
}

//age,month,year is type integer.
$name="Veo ve";
$age='10';
$month='';
$year='';
    $query="Insert Into tr_view(name,age,month,year) values ({toDB($name)},{toDB($age)},{toDB($month)},{toDB($year)})
 $db->setQuery($query);
 $result= $db->query();

Но это показывает ошибку:

 pg_query(): Query failed: ERROR: syntax error at or near "{" LINE 153: {toDB(10)}, ^ in...

Зачем?

2 ответа

Решение

Пока Эрвин отвечает NULLIF это здорово, это не относится к вашей синтаксической ошибке.

Давайте посмотрим на запрос:

$query="Insert Into tr_view(name,age,month,year) values ({toDB($name)},{toDB($age)},{toDB($month)},{toDB($year)})

Ранее вы определили функцию под названием toDB, К сожалению, синтаксис, который вы здесь используете, не в том, как вызывать функцию из строки в двойных кавычках, поэтому curlies и toDB( биты все еще передаются. Есть две альтернативы:

  1. Конкатенация с использованием .:

    $query='insert Into tr_view(name,age,month,year) values (' . toDB($name) . ',' . toDB($age) . ',' . toDB($month) . ',' . toDB($year) . ')')
    
  2. Таким образом, вы можете интерполировать вызываемую переменную в строку в двойных кавычках:

    $fn = 'toDB';
    $query="Insert Into tr_view(name,age,month,year) values ({$fn($name)},{$fn($age)},{$fn($month)},{$fn($year)})";
    

Первый ясен и вменяем, второй неясен для незнакомых и совершенно безумных.

Тем не менее, вы все равно не должны собирать ввод, как это. Вы все еще можете быть уязвимы к атакам SQL-инъекций Вы должны использовать подготовленные операторы с параметризованными заполнителями.

Расширение Postgres использует pg_prepare за это. Они имеют явное преимущество, скажем, позволяя вам пройти PHP null вместо того, чтобы беспокоиться обо всем этом нулевом обнаружении и цитировании.

Если вы настаиваете на сохранении toDB как есть, рассмотрите возможность добавления одного из pg_escape_ функции, как pg_escape_string к тому, что строит цитируемые строки.

Здесь NULLIF() функция:

SELECT NULLIF(var, '');

Если var держит значение в $2, вы получаете NULL вместо.
В примере я заменяю пустую строку: '' с NULL,

Нет пустой строки для типа integer. Просто не возможно. "Пусто" исключительно для строковых типов, таких как text или же varchar, поскольку NULLIF() не может переключить тип данных, вы должны очистить ваш ввод в PHP.

Если вы не определили столбец по умолчанию, вы также можете просто опустить столбец в INSERT команда и она будет заполнена NULL (который используется по умолчанию DEFAULT).

Проверьте, является ли параметр пустым в PHP, и не включайте столбец в INSERT Команда, если это так.

Или используйте вместо этого буквальный NULL PHP, как показано здесь @Quassnoi.


Остальное имеет смысл только для строковых типов.

Чтобы быть абсолютно уверенным, никто не может ввести пустую строку добавить CHECK ограничение к таблице:

ALTER TABLE tr_view
ADD CONSTRAINT tr_view_age_not_empty CHECK (age <> '');

Чтобы избежать исключений, вызванных этим, вы можете добавить триггер, который автоматически исправляет ввод:

CREATE OR REPLACE FUNCTION trg_tr_view_avoid_empty()
  RETURNS trigger AS
$BODY$
BEGIN
   IF NEW.age = '' THEN
      NEW.age := NULL;
   END IF;

   IF NEW.month = '' THEN
      NEW.month := NULL;
   END IF;

   RETURN NEW;
END
$BODY$ LANGUAGE plpgsql

CREATE TRIGGER log_up
BEFORE INSERT OR UPDATE ON tr_view
FOR EACH ROW
WHEN (NEW.age = '' OR NEW.month = '')
EXECUTE PROCEDURE trg_tr_view_avoid_empty();
Другие вопросы по тегам