postgres change data type of view column from unknown to text - postgresql

I just create a new view as follows
CREATE OR REPLACE VIEW gettreelistvw AS
SELECT "CRM".groupid, 'pointrewarding'::text AS applicationid, "CM".menuid, "CM".menuname, "CM".levelstructure, "CM".moduleid, "CM".haschild, "CM".installed
FROM core_capabilitymap "CRM"
JOIN core_menus "CM" ON "CRM".menuid::text = "CM".menuid::text;
ALTER TABLE gettreelistvw
when i execute this error appear
ERROR: cannot change data type of view column "applicationid" from
unknown to text
although I already cast the value of applicationid column to text. it's still recognized as unkown datatype
'pointrewarding'::text
The alternative method of postgres conversion also didn't work.
CAST('pointrewarding' AS TEXT)
How to solve this problem.

If you want to change the data type of a view's columns, you have to drop it, then create it.
Version 9.2 docs
CREATE OR REPLACE VIEW .... The new query must generate the same columns that were generated by the existing view query (that is, the same column names in the same order and with the same data types), but it may add additional columns to the end of the list.
Emphasis added.

Related

Ambiguous column reference "ctid" in SELECT with more than one table

I'm using CRecordset to query one table, but I use a second table to filter data. If in my GetDefaultSQL override method I return a table list with more than one table then I get this ERROR: column reference "ctid" is ambiguous. I know what a "ctid" column is, but I don't use it in my code. It's inserted into the original SQL statement by ODBC driver. How to fix this? How to tell the ODBC driver not to insert the "ctid" column?
I tried to call CRecordset::Open with readOnly parameter, as I assume that ODBC needs ctid to update the row, and I don't need to update them. But the error remains.
Also tried to add a primary key to the second table that was missing it, thinking if a table has a primary key then ODBC can use that instead of 'ctid', but again no luck. Makes sense though, because I don't fetch any column of that second table, and the second table is used just for filtering.
If I make a DB view to work around the issue, I get ERROR: column "ctid" does not exist.
You have to call CRecordset::Open with two parameters changed:
m_pSet->Open(CRecordset::snapshot, NULL, CRecordset::readOnly);
Then you can fetch both the joined tables and the view without errors. No "ctid" then.

How to add a column in the existing table and update all the existing data in postgresql?

I have an existing table, I want to insert a new column and update values in the whole table so that I do not have to refill the table again.
But the problem is, I have a route column which is present in the format shown below. I want to add a new column route_name where I will not include data after the 2nd underscore '_'
How do I do this by running a query?
route route_name (should look like)
dehradun_delhi_09:30_am dehradun_delhi
katra_delhi_07:30_pm katra_delhi
delhi_katra_08:00_pm delhi_katra
bangalore_chennai_10:45_pm bangalore_chennai
delhi_lucknow_09:00_pm delhi_lucknow
chennai_bangalore_10:30_pm chennai_bangalore
lucknow_varanasi_10:30_pm lucknow_varanasi
varanasi_lucknow_09:30_pm varanasi_lucknow
delhi_katra_08:00_pm delhi_katra
katra_delhi_07:30_pm katra_delhi
delhi_jalandhar_10:00_pm delhi_jalandhar
jalandhar_delhi_11:00_am jalandhar_delhi
delhi_amritsar_11:00_pm delhi_amritsar
amritsar_delhi_11:00_pm amritsar_delhi
Please tell me what query should I run so that the data backfilled also gets updated and a new column called route_name gets updated in the existing table
You need to do this in two steps.
First you add the column:
alter table route_table add column route_name text;
and then populate it:
update route_table set route_name=split_part(route,'_',1)

Why can't Update set change data type Postgres

I have a CSV which contains numbers stored as strings example: 1,200 when loading in these are stored as VARCHAR
I'd like to store these as integers. So tested the below;
update data
set stringy_number = replace (stringy_number,',','')::integer
This runs and removes the , from the number but doesn't change the character type. I then tried;
update data
set stringy_number::integer = replace (stringy_number,',','')::integer
Which threw a syntax error. At which point I switched to the below which worked, but I don't understand why I can't set a data type along with an update
alter table data
alter column stringy_number type integer using replace(stringy_number,',','')::integer;
update works on the values. You can cast from a datatype to another, but the result is still cast to to underlying column type.
--> you can save a "number" in a text column because it is easy to cast a number to a text. You cannot save a letter in a numerical column because the cast cannot (easily) be done.
alter column works on the entire column type. When changing the type, you can supply a custom transformation method allowing the old data to match the new data type.

Is it possible to change column type in a materialized view?

I'm pretty sure it's not:
ALTER MATERIALIZED VIEW myview ALTER COLUMN quantity SET TYPE integer;
produces:
ERROR: "myview" is not a table, composite type, or foreign table
But just wanted to check I hadn't missed something in the documentation.
The data type of a column in a materialized view is derived from the SELECT statement that is stored alongside the mview.
To change the data type of such a column you need to add the appropriate cast inside the SELECT and then refresh the mview.

How To change or alter column type in Views using PostgreSQL?

I have a view, one of he column is timetaken type integer i want to change it as numeric.For this I used below syntax
ALTER VIEW view_timesheets ALTER COLUMN timetaken type numeric;
When I run this I got the exception as
"view_timesheets" is not a table, composite type, or foreign table
Please explain how to alter column type.Thank You
It is not possible. You will have to recreate the view by providing its complete definition. Also note that you cannot even CREATE OR REPLACE VIEW when you change the types of the columns. If you have views that depend on the view that changes you will have to DROP / CREATE them also.
In my company we use the strategy where everything that is recreatable in a database (like views, functions, etc.) is stored in a bunch of large SQL files which we execute everytime anything changes in the underlying table structures, so we don't have to care for dependant views.
The view part in these files is basically like:
DROP VIEW IF EXISTS vw_a CASCADE;
CREATE OR REPLACE VIEW vw_a AS
...;
DROP VIEW IF EXISTS vw_b_depending_on_a CASCADE;
CREATE OR REPLACE VIEW vw_b_depending_on_a AS
...;
Of course the second CASCADE as well as the OR REPLACE seems useless, but they maek it possible to copy&paste changed definitions easily into a running dev database without much thinking.
I have also faced a similar problem while converting the column type of view.
I used the CAST() operator to convert the type from Integer to Varchar(5).
I had a column named age which is of type Integer in my table. So the view query created using that table was also having the type as Integer. So I used the CAST() operator in my view query to change the column type.
CASE
WHEN vhcl_insp_dtls.age = 0 THEN CAST('NEW' AS VARCHAR(5))
ELSE CAST(vhcl_insp_dtls.age AS VARCHAR(5))
END AS age,
So In this way, you can modify your view query without dropping it.