Как преобразовать пустой в ноль в 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(
биты все еще передаются. Есть две альтернативы:
Конкатенация с использованием
.
:$query='insert Into tr_view(name,age,month,year) values (' . toDB($name) . ',' . toDB($age) . ',' . toDB($month) . ',' . toDB($year) . ')')
Таким образом, вы можете интерполировать вызываемую переменную в строку в двойных кавычках:
$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();