To replace NULL values with an empty string, use COALESCE(column_name, ''). You'll need to know the column name and do this for each column name.
To convert a column into text, you can use column_name::TEXT or CAST(column_name AS TEXT). You'll also need to know the column names.
If you just want something quick and dirty that achieves something close to your goal, you can convert the whole row tuple into text:
SELECT my_table::TEXT FROM my_table
In this case, you'll get parentheses around the row which each value separated by a column. It's generally not ideal, and you'll lose the column name information, but could be handy if you want a quick and simple text search for example. (I'm sure there are better solutions to that particular problem.)
Another option, which may depend on the client you're using, is to use COPY (or psql's \copy) and export your data in CSV format to the standard output or to a file. There are more details on this in other answers.
The default CSV value for NULL is the empty string, but you could have quotes or something else using WITH NULL AS ...
You could also use some dynamic PL/pgSQL to create your query. Building the query could look like this:
SELECT 'SELECT '
|| string_agg('COALESCE('
|| attname::TEXT
|| '::TEXT, '''')' , ',' ORDER BY attnum)
|| ' FROM my_table'
INTO q
FROM pg_attribute WHERE attrelid = 'my_table'::regclass
AND attnum > 0 AND NOT attisdropped;
It's then a problem regarding how you want to return those results (since you'd may to know the columns in advance for using record or row types).
Since you're only interested in text, you might as well return each row as a TEXT array:
CREATE OR REPLACE FUNCTION my_function() RETURNS SETOF TEXT[]
AS $$
DECLARE
q TEXT;
r TEXT[];
BEGIN
SELECT 'SELECT ARRAY['
|| string_agg('COALESCE('
|| attname::TEXT
|| '::TEXT, '''')' , ',' ORDER BY attnum)
|| '] FROM my_table'
INTO q
FROM pg_attribute WHERE attrelid = 'my_table'::regclass
AND attnum > 0 AND NOT attisdropped;
FOR r IN EXECUTE q
LOOP
RETURN NEXT r;
END LOOP;
END
$$ LANGUAGE plpgsql;
SELECT my_function();
Answer from Bruno on Stack OverflowHow to convert empty string ('') as NULL in postgres in config level.
sql - PostgreSql remove difference between null and empty string - Stack Overflow
sql - Cast string to number, interpreting null or empty string as 0 - Stack Overflow
php - How to convert empty to null in PostgreSQL? - Stack Overflow
HI Team,
Kindly help to convert empty string to null in postgres.
SELECT 1 FROM DUAL WHERE ( SELECT '' FROM dual) IS NULL
In the above query SELECT '' FROM dual returns empty string in postgres. but in oracle it is returning as null.
hence there is a functionality mismatch in the output. how can i convert this empty string as null in config level. other than nullif function.
The types of values need to be consistent; coalescing the empty string to a 0 means that you cannot then compare it to null in the nullif. So either of these works:
# create table tests (orig varchar);
CREATE TABLE
# insert into tests (orig) values ('1'), (''), (NULL), ('0');
INSERT 0 4
# select orig, cast(coalesce(nullif(orig,''),'0') as float) as result from tests;
orig | result
------+--------
1 | 1
| 0
| 0
0 | 0
(4 rows)
# select orig, coalesce(cast(nullif(orig,'') as float),0) as result from tests;
orig | result
------+--------
1 | 1
| 0
| 0
0 | 0
(4 rows)
You could also use
cast(
case
when coalesce(orig, '') = '' then '0'
else orig
end
as float
)
You could also unwrap that a bit since you're being fairly verbose anyway:
cast(
case
when orig is null then '0'
when orig = '' then '0'
else orig
end
as float
)
or you could put the cast inside the CASE:
case
when coalesce(orig, '') = '' then 0.0
else cast(orig as float)
end
A CASE makes it a bit easier to account for any other special conditions, this also seems like a clearer expression of the logic IMO. OTOH, personal taste and all that.
There is the NULLIF() function:
SELECT NULLIF(var, '');
If var equals the 2nd parameter, you get NULL instead.
The example replaces the empty string '' with NULL.
There is no "empty string" for the type integer. Both parameters must be of compatible type, so 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
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 FUNCTION trg_tr_view_avoid_empty();
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:
Concatenation using
.:$query='insert Into tr_view(name,age,month,year) values (' . toDB($name) . ',' . toDB($age) . ',' . toDB($month) . ',' . toDB($year) . ')')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.
Hello!
I am making an application with a postgres interface. The Framework I am working with allows me to to instantiate variables in the form of $var. The Postgres part is actually fine, the framework is what is causing me problems and I wanted to ask if I could solve this problem within postgres myself.
Say, in my framework I have a variable $var, which I have assigned $var = null
The crucial part looks like this:
case when $var is not null then name else 'NULLVALUE' end = coalesce($var , 'NULLVALUE')
If I do:
case when null is not null then name else 'NULLVALUE' end = coalesce(null , 'NULLVALUE')
Then the query works fine. However, the interface, translates $var = null as an empty string. So, in my query, instead of null, I have an empty string, like so:
case when is not null then name else 'NULLVALUE' end = coalesce( , 'NULLVALUE')
Is there any workaround? Any way you would achieve this works for starters, really.
I was thinking that if we could actually check before running the query, so check if $var is an empty string or assign the values to variables within the postgres part and null to the empty values - is there a way to do this? (Aside from Rel Algebra (inc. calculus), Normalization and Database design, I've learnt how do many sorts of queries in SQL and how to manipulate tables - things such as this I haven't had experience with, I'm sorry)
While I am looking into a solution in my framework, there's just a handful of people who know their way around this. So while I've asked in this framework's respective forum, I've figured it might be faster, if there is a possible solution within postgres itself.