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

2022-08-30 19:22:39

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

为什么?


答案 1

NULLIF() 函数:

SELECT NULLIF(var, '');

如果等于第 2 个参数,则改为
该示例将空字符串替换为 。varNULL''NULL

整数类型没有“空字符串”。这两个参数必须是兼容的类型,因此请在PHP中清理输入。

如果未定义列默认值,则也可以省略命令中的,它将被填充(这是默认值)。INSERTNULLDEFAULT

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

或者使用PHP文字NULL代替,就像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
  LANGUAGE plpgsql 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$;

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();

答案 2

虽然Erwin的答案很棒,但它并没有解决你的语法错误。NULLIF

让我们看一下查询:

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

之前您定义了一个名为 的函数。不幸的是,您在此处使用的语法不是如何从双引号字符串中调用函数,因此卷曲和位仍在传递。有两种选择:toDBtoDB(

  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

如果您坚持保持原样,请考虑将其中一个函数(如pg_escape_string)添加到构建带引号的字符串的事物中。toDBpg_escape_


推荐