【问题标题】:How to convert empty to null in PostgreSQL?如何在 PostgreSQL 中将空转换为空?
【发布时间】:2012-12-11 17:36:51
【问题描述】:

我有一些列类型为 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...

为什么?

【问题讨论】:

  • 不能将 '' 插入 int,只能插入整数或空值。

标签: php postgresql null


【解决方案1】:

NULLIF()函数:

SELECT NULLIF(var, '');

如果var 持有$2 中的值,您将获得NULL
在示例中,我将空字符串:'' 替换为 NULL

整数类型没有空字符串。只是不可能。由于NULLIF() 无法切换数据类型,您必须在 PHP 中清理您的输入。

如果您没有定义列默认值,您也可以在INSERT 命令中省略列,它将用NULL 填充(这是默认的DEFAULT) .

检查PHP中参数是否为空,如果是则不要在INSERT命令中包含该列。

或者使用 PHP 文字 NULL 代替,就像 Quassnoi 演示的 here

其余的只对字符串类型有意义

为了绝对确定,任何人都不能输入空字符串,在表格中添加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
$func$
BEGIN
   IF NEW.age = '' THEN
      NEW.age := NULL;
   END IF;

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

   RETURN NEW;
END
$func$  LANGUAGE plpgsql

CREATE TRIGGER tr_view_avoid_empty
BEFORE INSERT OR UPDATE ON tr_view
FOR EACH ROW
WHEN (NEW.age = '' OR NEW.month = '')
EXECUTE PROCEDURE trg_tr_view_avoid_empty();

【讨论】:

  • 我知道谢谢 cmets 很气馁,但我会继续说谢谢。
【解决方案2】:

虽然 Erwin 关于 NULLIF 的回答很棒,但它并没有解决您的语法错误。

我们来看看查询:

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

之前您定义了一个名为toDB 的函数。不幸的是,您在这里使用的语法是 not 如何从双引号字符串中调用函数,因此 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 injection attacks 的攻击。你应该使用prepared statements with parameterized placeholders

Postgres 扩展为此使用pg_prepare。它们具有明显的优势,例如,允许您传递 PHP null,而不必担心所有空值检测和引用。

如果您坚持保持toDB 原样,请考虑将pg_escape_ 函数之一,如pg_escape_string,添加到构建引用字符串的事物中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-12
    • 2012-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    • 2012-10-14
    • 2020-03-22
    • 1970-01-01
    相关资源
    最近更新 更多