如何在PostgreSQL中将空转换为null?

D T*_*D T 7 php postgresql null

我有一些列类型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();
Run Code Online (Sandbox Code Playgroud)

但它显示错误:

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

为什么?

Erw*_*ter 44

NULLIF()功能:

SELECT NULLIF(var, '');
Run Code Online (Sandbox Code Playgroud)

如果var保持$ 2的价值,你会得到NULL.
在示例中,我替换空字符串:''with NULL.

该类型的整数无空字符串.只是不可能."Empty"是字符串类型的唯一,如NULLIF()INSERT.由于NULL无法切换数据类型,因此必须在PHP中清理输入.

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

检查PHP中的参数是否为空,如果是,则不在NULLIF()命令中包含该列.

或者使用PHP文字NULL,就像@Quassnoi 在这里演示一样.


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

为了绝对确定,没有人可以输入空字符串var向表中添加约束:

ALTER TABLE tr_view
ADD CONSTRAINT tr_view_age_not_empty CHECK (age <> '');
Run Code Online (Sandbox Code Playgroud)

避免由此引起的异常,您可以添加一个自动修复输入的触发器:

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();
Run Code Online (Sandbox Code Playgroud)

  • 我知道谢谢你的评论是气馁的,但我会继续说谢谢. (3认同)

Cha*_*les 7

尽管欧文的约答案NULLIF真棒,它没有解决您的语法错误.

我们来看看查询:

$query="Insert Into tr_view(name,age,month,year) values ({toDB($name)},{toDB($age)},{toDB($month)},{toDB($year)})
Run Code Online (Sandbox Code Playgroud)

之前您定义了一个名为的函数toDB.不幸的是,你在这里使用的语法不是如何从双引号字符串中调用函数,所以curlies和toDB(bits仍在传递.有两种选择:

  1. 连接使用.:

    $query='insert Into tr_view(name,age,month,year) values (' . toDB($name) . ',' . toDB($age) . ',' . toDB($month) . ',' . toDB($year) . ')')
    
    Run Code Online (Sandbox Code Playgroud)
  2. 您可以将可调用变量插入到双引号字符串中:

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

第一个是明确和理智,第二个是模糊的陌生和彻头彻尾的疯狂.

但是,您仍然不应该像这样组装输入.您仍然可能容易受到SQL注入攻击.您应该使用带参数化占位符的预准备语句.

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

如果你坚持保持toDB原样,可以考虑将其中一个pg_escape_函数添加pg_escape_string到构建引用字符串的东西中.