Как преобразовать empty в null в PostgreSQL?

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

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 is высокий, он не решает вашу синтаксическую ошибку.

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

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

раньше вы определили функцию с именем toDB. К сожалению, синтаксис, который вы используете здесь не как вызвать функцию из строки с двойными кавычками, так что кудри и 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() не могу переключить тип данных, вы должны санировать ввод в РНР.

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

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

или использовать PHP литерал NULL вместо этого, как @Quassnoi показывает здесь.


остальное имеет смысл только для типов string

до быть абсолютно уверенными, никто не может ввести пустую строку добавить 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();