postgresql changing column type from array to integer throwing casting error - sql

I am changing the postgresql column data type from integer[] to integer, while executing below query,
alter table contact_type alter column is_delete set data type integer USING is_delete::integer
i am getting below error
ERROR: cannot cast type integer[] to integer
LINE 1: ...umn is_delete set data type integer USING is_delete::integer
^
SQL state: 42846
Character: 86
but when tried to change datatype from varchar[] to char, below query works fine
alter table contact_type alter column ct_type set data type varchar
i have referred this link so link but it is not working for converting array to normal data type..
Edit :- it is empty table without any data...

You need to pick the array element that you want to use. You can't convert e.g. 42 integers to a single one.
E.g. if you want to use the first element of the array:
alter table contact_type
alter column is_delete
set data type integer USING is_delete[1];
But a column named is_delete should probably be a boolean rather than an integer.

Related

Change column type from text to integer

I have column with type text
I need to change column type to integer.
I try to do it with the following script
ALTER TABLE table ALTER COLUMN column TYPE integer
Obviously I get an error.
But how can I modify my script if my previous values were like "Word1", "Word2" and now I want to keep them like 0, 1
If it possible I would be Ok if this script will set 0 to all rows when processing this script.
If your column contains only integer values then try this way:
ALTER TABLE test ALTER COLUMN id TYPE integer USING (id::integer);
If your column contains non-numeric values then try this way:
ALTER TABLE test ALTER COLUMN id TYPE integer USING (CASE
WHEN id~E'^\\d+$' THEN
CAST (id AS INTEGER)
ELSE
0
END);
DEMO

Error: invalid input syntax for type numeric: "" (postgresql)

I'm trying to alter the column data type in my postgresql table. The column name is _2010_10, type is text, and the value is 18.74 (in text format). I'm trying to change the text type to numeric. This is my input/output:
ALTER table cadata.pricetorentratio
ALTER column _2010_10 type numeric USING (trim(_2010_10)::numeric);
ERROR: invalid input syntax for type numeric: ""
Not sure why I'm getting this error.
You could use NULLIF to handle blank string '':
ALTER table pricetorentratio
ALTER column _2010_10 type numeric USING (NULLIF(trim(_2010_10),'')::numeric);
DBFiddle Demo
SELECT ''::numeric
-- invalid input syntax for type numeric: ""
ALTER TABLE `pricetorentratio` CHANGE `_2010_10` `_2010_10` FLOAT NULL DEFAULT NULL;

Can't convert postgresql table column from type varchar to int

I have a database table of that I have used to store the data returned from a web spider. I have a column that contains ticket prices for different events all in the varchar type (as the scrapy spider has to scrape the data in unicode). I'm trying to return the min price of the column and since the min() function only works for data of type INT, I tried to convert the column to integers using a solution from this SO post:
ALTER TABLE vs_tickets ALTER COLUMN ticketprice TYPE integer USING (ticketprice::integer);
but I got the error: ERROR: invalid input syntax for integer:
I also tried: change_column :vs_tickets, :ticketprice, 'integer USING CAST(ticketprice AS integer)' but that didn't work either.
What is the proper way to convert the column to type INT?
Edit:
You have decimal places in the string, so a simple cast is not going to work. You can do a double conversion:
cast(cast(ticketprice as decimal(10, 2)) as int)
or:
(ticketprice::decimal(10, 2))::int
(The parens are not strictly necessary.)
EDIT:
Or, as Erwin points out, just use numeric:
(ticketprice::numeric)::int
Postgres is much smarter about numeric than most other databases . . . after all, it supports numbers that are egregiously large ;)
The final query is:
ALTER TABLE vs_tickets
ALTER COLUMN ticketprice TYPE integer USING (ticketprice::numeric::integer);
I'm going to bet on your column have wrong characters.
Also you may want use float or numeric because you will lose decimals if convert to integers.
You need create a function to check if a text is numeric like this isnumeric-with-postgresql
Then check each row like this
select ticketprice
from vs_tickets
where ISNUMERIC(ticketprice) = false;
As your comment you also should try
SELECT ticketprice::float
You will be best off adding an INT column, moving your data with a cast and then removing the old varchar column.
ALTER TABLE vs_tickets ADD COLUMN ticketprice_int TYPE int;
GO
update vs_tickets SET ticketprice_int = cast(ticketprice as int);
// if you fail to cast the varchar to int you can use Gordon's method
// update vs_tickets SET ticketprice_int = cast(cast(ticketprice as decimal(10, 2)) as int);
GO
ALTER TABLE vs_tickets DROP COLUMN ticketprice;
GO
ALTER TABLE vs_tickets RENAME COLUMN ticketprice_int to ticketprice;
GO
With this at minimum you will be able to tell if and where a cast/convert fails and be able to check and recheck at each step before you can't turn back.

Change column datatype from Text to Integer in PostgreSQL [duplicate]

This question already has answers here:
Rails Migrations: tried to change the type of column from string to integer
(6 answers)
Closed 8 years ago.
I am using the following query to change the data type of a column from text to integer but getting error:
alter table a.attend alter column terminal TYPE INTEGER ;
ERROR: column "terminal" cannot be cast automatically to type integer
create table test(id varchar );
insert into test values('1');
insert into test values('11');
insert into test values('12');
select * from test
--Result--
id
character varying
--------------------------
1
11
12
You can see from the above table that I have used the data type – character varying for id
column. But it was a mistake because I am always giving integers as id. So using varchar here is a bad practice. So let’s try to change the column type to integer.
ALTER TABLE test ALTER COLUMN id TYPE integer;
But it returns:
ERROR: column “id” cannot be cast automatically to type integer SQL
state: 42804 Hint: Specify a USING expression to perform the
conversion
That means we can’t simply change the data type because data is already there in the column. Since the data is of type character varying Postgres can't expect it as integer though we entered integers only. So now, as Postgres suggested we can use the USING expression to cast our data into integers.
ALTER TABLE test ALTER COLUMN id TYPE integer USING (id::integer);
It Works.
So you should use
alter table a.attend alter column terminal TYPE INTEGER USING (terminal::integer) ;

Altering JSON column to INTEGER[] ARRAY

I have a JSON column that contains an array of integers. I am trying to convert it to an INTEGER[] column, but I'm running into casting errors.
Here's my final alter version:
ALTER TABLE namespace_list ALTER COLUMN namespace_ids TYPE INTEGER[] USING string_to_array(namespace_ids::integer[], ',');
However, this throws this error:
ERROR: cannot cast type json to integer[]
Any ideas how I can abouts this conversion? I've tried several things but I end up with the same error. Seems like going json --> string --> --> array does not work. What are my options?
Edit:
Table definition:
db => \d+ namespace_list;
Column | Type | Table "kiwi.namespace_list" Modifiers|
---------------+----------+--------------------------------------+
id | integer | not null default nextval('namespace_list_id_seq'::regclass)
namespace_ids | json | not null default '[]'::json
Sample data:
id | namespace_ids |
-------------------+
1 | [1,2,3] |
Assuming no invalid characters in your array.
IN Postgres 9.4 or later use a conversion function as outlined here:
How to turn JSON array into Postgres array?
CREATE OR REPLACE FUNCTION json_arr2int_arr(_js json)
RETURNS int[] LANGUAGE sql IMMUTABLE PARALLEL SAFE AS
'SELECT ARRAY(SELECT json_array_elements_text(_js)::int)';
ALTER TABLE namespace_list
ALTER COLUMN namespace_ids DROP DEFAULT
, ALTER COLUMN namespace_ids TYPE int[] USING json_arr2int_arr(namespace_ids);
db<>fiddle here
For Postgres 9.3 or older:
ALTER TABLE namespace_list
ALTER COLUMN namespace_ids TYPE INTEGER[]
USING translate(namespace_ids::text, '[]','{}')::int[];
The specific difficulty is that you cannot have a subquery expression in the USING clause, so unnesting & re-aggregating is not an option:
SELECT ARRAY(SELECT(json_array_elements(json_col)::text::int))
FROM namespace_list;
Therefore, I resort to string manipulation to produce a valid string constant for an integer array and cast it.
column DEFAULT
If there is a column default like DEFAULT '[]'::json in your actual table definition added later, drop it before you do the above.
You can add a new DEFAULT afterwards if you need one. Best in the same transaction (or even command):
ALTER TABLE namespace_list
ALTER COLUMN namespace_ids DROP DEFAULT
, ALTER COLUMN namespace_ids TYPE INT[] USING translate(namespace_ids::text, '[]','{}')::int[]
, ALTER COLUMN namespace_ids SET DEFAULT '{}';
db<>fiddle here
Old sqlfiddle