Add new column in VERTICA and retaining old projections - vertica

I want to add a column on any position in my table in VERTICA. What I am doing is creating the new table with added column and copying the data from old table to new then dropping the old table. But I also want to copy the old projections to the new table. How should I do it?
P.S. I am writing an automated code for it.

Below is another method
Assumes below is your source table :
CREATE TABLE public.test5 ( id int, zz int, zz1 int);
CREATE PROJECTION public.test5_prj ( id, zz, zz1)AS SELECT test5.id, test5.zz, test5.zz1 FROM public.test5
ORDER BY test5.id SEGMENTED BY hash(test5.id) ALL NODES KSAFE 1;
And you like to copy all the projections from source table to target table + adding column in the middle (new_id type int)
You can you the below technic to modify your source projection to reflect your target structure
[dbadmin#mydphdb0184 ~]$ echo "select export_objects('','public.test5');"|vsql -U dbadmin -w dbadmin| sed -n '/CREATE PROJECTION/,/;/p'|sed "s/id,/id,new_id/g"
The ourout the new projection that reflect your target stracure
CREATE PROJECTION public.test5 /+createtype(A)/
(
id,new_id
zz,
zz1
)
AS
SELECT test5.id,new_id
test5.zz,
test5.zz1
FROM public.test5
ORDER BY test5.id
SEGMENTED BY hash(test5.id) ALL NODES KSAFE 1;

You may want to use this syntax :
create table date_dimcopy like date_dimension including projections;
Thanks

Related

How to change PARTITION in clickhouse

version 18.16.1
CREATE TABLE traffic (
`date` Date,
...
) ENGINE = MergeTree(date, (end_time), 8192);
I want to change as PARTITION BY toYYYYMMDD(date) without drop table how to do that.
Since ALTER query does not allow the partition alteration, the possible way is to create a new table
CREATE TABLE traffic_new
(
`date` Date,
...
)
ENGINE = MergeTree(date, (end_time), 8192)
PARTITION BY toYYYYMMDD(date);
and to move your data
INSERT INTO traffic_new SELECT * FROM traffic WHERE column BETWEEN x and xxxx;
Rename the final table if necessary.
And yes, this option involves deleting the old table (seems to be no way to skip this step)

Copying the data from the old table to the new table with only different new table has sequence

I need to create a new table from old one, need to insert the rows from the old one, only change is the new sequence column needs to be added in the new one.
Can someone please help me for the same?
INSERT INTO dps_session_map (TrackSESSION_SEQ,session_seq, column3)
   SELECT
        A.SEQ_Session.NEXTVAL, sm.session_seq, sm.column3
    FROM 
        dps_session_map  A,
        dps_exec_session_map sm
WHERE sm.session_seq is not null;
Remove the VALUES keyword and its brackets:
--general pattern of inserting from one table to another existing table
INSERT INTO table(columns)
SELECT columns FROM othertable
Column count and type must match (or be implicitly convertible)
If your new table doesn't exist, do:
CREATE TABLE x AS
(SELECT columns FROM othertable)
INSERT INTO dps_session_map (TrackSESSION_SEQ,session_seq, column3)
SELECT
**SCHEMA.**SEQ_Session.NEXTVAL, sm.session_seq, sm.column3
FROM
dps_session_map A,
dps_exec_session_map sm
WHERE sm.session_seq is not null;
Reference the sequence by its name or fully qualified schema.name. Sequences don't belong to table. Are you getting a "ORA-02289: sequence does not exist" error?

Modify a nested table in Oracle

I have the below Nested table created :
create or replace TYPE access_t AS OBJECT (
AccessID VARCHAR2(50),
Eligibility char(1)
);
/
create or replace TYPE Access_tab IS TABLE OF access_t;
/
create or replace TYPE add_t AS OBJECT (
city VARCHAR2(100),
state VARCHAR2(100),
zip VARCHAR2(10),
APOINTSARRAY Access_tab )
;
/
create or replace TYPE add_tab IS TABLE OF add_t;
/
CREATE TABLE RQST_STATUS
( RQST_ID NUMBER,
ADDRESS add_tab
)
NESTED TABLE ADDRESS STORE AS RQST_STATUS_ADDRESS
( NESTED TABLE APOINTSARRAY STORE AS RQST_STATUS_AP)
;
If i need to change ADDRESS type to new_add_tab with some additional columns instead of add_tab , Can i just use ALTER TABLE .. MODIFY .. command ?
I am getting ORA-00922 or ORA-22913 errors . I cannot change the type directly because it is used somewhere else too. Also, the table is already loaded with data.
Please suggest.
You can do that but you have to alter the TYPE not the TABLE.
Check the documentation ALTER TYPE Statement: alter_method_spec
Most important is the CASCADE key word.
Examples:
ALTER TYPE access_t ADD ATTRIBUTE NEW_Eligibility INTEGER CASCADE;
ALTER TYPE access_t DROP ATTRIBUTE Eligibility CASCADE;
ALTER TYPE access_t MODIFY ATTRIBUTE AccessID VARCHAR2(100) CASCADE;
Here is a step-by-step description of my suggestion. It might not be the most elegant, but I think that it would be best for you to have something you can fully understand (as opposed to an obscure trick).
Also, and since I don't really know what kind of changes you need to do for the internal table, I'm leaving the maximal flexibility for you to do any change you may wish to do.
Let's call your table T1 that contains a columns C_T which is your internal table.
The internal table contains columns C_1, C-2 and C_3, and you want the new structure for the record to be D_1, D_2, D_3, D_4 and D_5, where the mapping is:
C_1 -> D_5,
C_2 -> D_1,
C_3 -> D_2,
{new} -> D_3,
{new} -> D_4.
Create a tempo table TEMPO_T with a column SOURCE_ROWID (varchar2(64)) and the new columns D_1,..., D5.
Write a small anonymous block having a cursor that selects the ROWID of each row of table T1 and all the records within the internal table in column C_T (order by ROWID). The result would look like (this is just an example of course):
ROWID C_1 C_2 C_2
wwereeedffff 1 a ww
wwereeedffff 2 b xx
wwereeedffff 7 l yy
ertrtrrrtrrr 5 d PP
ertrtrrrtrrr 99 h mm
...
[Note: The use of ROWID is under the assumption that you don't have a column that can serve as a unique identifier for each row in table T1; if there is such column - one defined as UNIQUE INDEX - you can use that field instead]
Having this query ready, convert it into an INSERT into the temporary table TEMPO_T along with whatever values you need to store for columns D_3 and D_4.
Now, you have a backup of the original contents of column C_T and hence can delete the column.
Now, you can update the type that defines the structure of column C_T to its new form (i.e. D_1,...,D_5) and alter table T1 by adding a column whose type is the updated one.
Finally, you can insert the contents of column C_T with that stored in the temporary table (since you already have this, I assume that you know how to implement it - inserting a table within a cell column of the outer table).
That's it.
Needless to say, I would make a backup of your data before engaging into this.
Hope this description is detailed enough to enable you to complete the task at hand.

In hive, is there a way to specify between which columns to add a new column to?

I can do
ALTER TABLE table_name ADD COLUMNS (user_id BIGINT)
to add a new column to the end of my non-partition columns and before my partition columns.
Is there any way to add a new column to anywhere among my non-partition columns?
For example, I would like to put this new column user_id as the first column of my table
Yes it is possible to change the location of columns but only after adding it in the table using CHANGE COLUMN
In your case, first add the column user_id to the table with below command:
ALTER TABLE table_name ADD COLUMNS (user_id BIGINT);
Now to make user_id column as the first column in your table use change column with FIRST clause:
ALTER TABLE table_name CHANGE COLUMN user_id user_id BIGINT first;
This will move the user_id column to the first position.
Similarly you can use After instead of first if you want to move the specified column after any other column. Like say, I want to move dob column after user_id column. Then my command would be:
ALTER TABLE table_name CHANGE COLUMN dob dob date AFTER user_id;
Please note that this commands changes metadata only. If you are moving columns, the data must already match the new schema or you must change it to match by some other means.
Ah, here's the explanation for why you listed user_id twice (it's not a type):
// Next change column a1's name to a2, its data type to string, and put it after column b.
ALTER TABLE test_change CHANGE a1 a2 STRING AFTER b;
// The new table's structure is: b int, a2 string, c int.
No, it is not possible.
One solution is to create new table using "CREATE TABLE AS SELECT" approach and drop older one.

changing SRID of SDO_geometry from existing value without changing the original value

I have a Oracle database table with a column in SDO_GEOMETRY type. I am trying to write a view on this table and get the SDO_GEOMETRY column with different SRID. I don't want to change the original table or transform the value to a different SRID. I just want to get the geometry column with a different SID (same vertice values). How to achieve this?
The table is this:
Create Table Locations (CityCode VARCHAR(2), Location SDO_GEOMETRY)
I am trying to create a view like this for example:
CREATE OR REPLACE VIEW VW_Locations AS
SELECT
CityCode,
SDO_GEOMETRY(Location, <NEW_SRID>)
FROM Locations
I tried to use the constructor for SDO_GEOMETRY using WKT as parameter but i couldn't make it because the geometry values in my table are 3D and Oracle does not support WKT/WKB conversion of 3D SDO_GEOMETRY values. This one works for 2D geometries:
CREATE OR REPLACE VIEW VW_Locations AS
SELECT
CityCode,
SDO_GEOMETRY(SDO_UTIL.TO_WKTGEOMETRY(Location), <NEW_SRID>) AS Loc
FROM Locations
I tried the same approach as you, and had the same problem (TO_WKTGEOMETRY export only works for 2D geometries).
My current approach is to use a custom function to apply the SRID through the object dot notation:
CREATE OR REPLACE FUNCTION APPLY_SRID
(
GEOM IN OUT MDSYS.SDO_GEOMETRY
, SRID IN NUMBER DEFAULT 8307
) RETURN MDSYS.SDO_GEOMETRY AS
BEGIN
GEOM.SDO_SRID := SRID;
RETURN GEOM;
END APPLY_SRID;
In your own code, you would use this as follows:
CREATE OR REPLACE VIEW VW_Locations AS
SELECT
CityCode,
APPLY_SRID(Location, <NEW_SRID>)
FROM Locations

Resources