Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert empty to null in PostgreSQL?

I have some columns type int, but value is empty. So I want to convert empty to null when I insert to database. I use code:

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

But it show error:

 pg_query(): Query failed: ERROR: syntax error at or near ";" LINE 153: {toDB(10)}, ^ in...

Why?

like image 239
D T Avatar asked Dec 26 '12 04:12

D T


People also ask

Does Postgres treat empty string as NULL?

PostgreSQL databases treat empty strings and NULL as different.

How do you change a blank NULL in SQL?

There are two ways to replace NULL with blank values in SQL Server, function ISNULL(), and COALESCE(). Both functions replace the value you provide when the argument is NULL like ISNULL(column, '') will return empty String if the column value is NULL.

How do I use NULL in PostgreSQL?

Let's look at an example of how to use PostgreSQL IS NULL in a SELECT statement: SELECT * FROM employees WHERE first_number IS NULL; This PostgreSQL IS NULL example will return all records from the employees table where the first_name contains a NULL value.

Does coalesce work on empty string?

If all the arguments are blank or empty strings then the function returns blank, making Coalesce a good way to convert empty strings to blank values.


2 Answers

There is the NULLIF() function:

SELECT NULLIF(var, '');

If var holds the value in $2, you get NULL instead.
In the example I replace the empty string: '' with NULL.

There is no empty string for the type integer. Just not possible. Since NULLIF() cannot switch the data type, you have to sanitize your input in PHP.

If you did not define a column default, you can also just omit the column in the INSERT command and it will be filled with NULL (which is the default DEFAULT).

Check if the parameter is empty in PHP and don't include the column in the INSERT command if it is.

Or use the PHP literal NULL instead like Quassnoi demonstrates here.

The rest only makes sense for string types

To make absolutely sure, nobody can enter an empty string add a CHECK constraint to the table:

ALTER TABLE tr_view
ADD CONSTRAINT tr_view_age_not_empty CHECK (age <> '');

To avoid exceptions caused by this, you could add a trigger that fixes input automatically:

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();
like image 139
Erwin Brandstetter Avatar answered Oct 04 '22 03:10

Erwin Brandstetter


While Erwin's answer about NULLIF is awesome, it doesn't address your syntax error.

Let's take a look at the query:

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

Earlier you defined a function called toDB. Unfortunately the syntax you are using here is not how to call a function from within a double-quoted string, so the curlies and toDB( bits are still being passed through. There are two alternatives:

  1. Concatenation using .:

    $query='insert Into tr_view(name,age,month,year) values (' . toDB($name) . ',' . toDB($age) . ',' . toDB($month) . ',' . toDB($year) . ')')
    
  2. You can interpolate a callable variable into a double-quoted string thusly:

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

The first is clear and sane, the second is vague to the unfamiliar and downright insane.

However, you still should not be assembling input like this. You still may be vulnerable to SQL injection attacks. You should be using prepared statements with parameterized placeholders.

The Postgres extension uses pg_prepare for this. They have the distinct advantage of, say, allowing you to pass a PHP null instead of having to worry about all of that null-detection and quoting.

If you insist on keeping toDB as-is, consider adding one of the pg_escape_ functions, like pg_escape_string, to the thing that builds quoted strings.

like image 31
Charles Avatar answered Oct 04 '22 02:10

Charles