Can I add a NOT NULL constraint to a CockroachDB column? - cockroachdb

I want to add NOT NULL to a column, but it looks like ADD CONSTRAINT doesn’t support it. How can I add the constraint?

Cockroach does not currently allow adding these constraints to an existing table.
One workaround is to create a new table with the schema you want to use (including the NOT NULL constraint), and then migrate the data to the new table using INSERT...SELECT.
Here’s an example:
CREATE TABLE tbl2 (id INT PRIMARY KEY, col_a INT NOT NULL);
INSERT INTO tbl2 SELECT * FROM tbl1;
This assumes that tbl1 has the same number of columns with the same types and doesn’t have any NULL values in its version of col_a.
The downside of this is that it has to copy all the table data, so it is not ideal on large tables.
Another workaround would be to add a new column, with the NOT NULL constraint (which implies it would also require a DEFAULT), then use an UPDATE to set its value from the existing column, then rename the new column and drop the old one.

Related

View the contents and constraints of a table

I am working on this assignment question and it is asking me:
To create a table called (TEMP_CUST) from an existing table Customers
View the content and constraints of TEMP_CUST table
What I have done so far is I have created my table, didn't add any constraints to the table TEMP_CUST and viewed the table using the DESC command.
Here is the code for table creation
CREATE TABLE TEMP_CUST
AS
(SELECT
CUSTOMER#, LASTNAME,
FIRSTNAME, ADDRESS, CITY,
STATE, ZIP, REFERRED,
REGION, EMAIL
FROM
CUSTOMERS);
DESC TEMP_CUST;
Now that I have done that I want to view the constraints of the table. I have used this command but am not sure if it is correct.
SELECT *
FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'TEMP_CUST';
i have used this command, but not sure if it is correct.
You haven't said why you don't think it's correct so we have to guess the reason for your doubt. Perhaps it's because the set of constraints you get is smaller than the set of constraints for the original CUSTOMERS table?
That is correct. When we use CREATE TABLE ... AS SELECT the statement creates a new table with the projection, column names and datatypes of the original tables (assuming a vanilla SELECT clause) and the data (determined by the WHERE clause, if any). However, the only constraints which are created are NOT NULL constraints on the primary key column(s) and any other mandatory columns. The new table does not have primary key, foreign key or check constraints. We have to create these explicitly.
Hence, this query ...
SELECT * FROM USER_CONSTRAINTS
WHERE TABLE_NAME = 'TEMP_CUST';
... might return fewer constraints than you were expecting.

How to modify data type in Oracle with existing rows in table

How can I change DATA TYPE of a column from number to varchar2 without deleting the table data?
You can't.
You can, however, create a new column with the new data type, migrate the data, drop the old column, and rename the new column. Something like
ALTER TABLE table_name
ADD( new_column_name varchar2(10) );
UPDATE table_name
SET new_column_name = to_char(old_column_name, <<some format>>);
ALTER TABLE table_name
DROP COLUMN old_column_name;
ALTER TABLE table_name
RENAME COLUMN new_column_name TO old_coulumn_name;
If you have code that depends on the position of the column in the table (which you really shouldn't have), you could rename the table and create a view on the table with the original name of the table that exposes the columns in the order your code expects until you can fix that buggy code.
You have to first deal with the existing rows before you modify the column DATA TYPE.
You could do the following steps:
Add the new column with a new name.
Update the new column from old column.
Drop the old column.
Rename the new column with the old column name.
For example,
alter table t add (col_new varchar2(50));
update t set col_new = to_char(col_old);
alter table t drop column col_old cascade constraints;
alter table t rename column col_new to col_old;
Make sure you re-create any required indexes which you had.
You could also try the CTAS approach, i.e. create table as select. But, the above is safe and preferrable.
The most efficient way is probably to do a CREATE TABLE ... AS SELECT
(CTAS)
alter table table_name modify (column_name VARCHAR2(255));
Since we can't change data type of a column with values, the approach that I was followed as below,
Say the column name you want to change type is 'A' and this can be achieved with SQL developer.
First sort table data by other column (ex: datetime).
Next copy the values of column 'A' and paste to excel file.
Delete values of the column 'A' an commit.
Change the data type and commit.
Again sort table data by previously used column (ex: datetime).
Then paste copied data from excel and commit.

Oracle Backup and restore constraints to allow changing a column type

I need to change a column type in more than 200 tables I am following the next recipe:
Disable all foreign constraints if the column is referenced by any FK
Store columns in varray and Drop primary key if the column is part of a PK
Create a temporal new column in the table with the same type
Update the temporal new column with original values
Delete values from original column
Change column type of original column
Update original column with temporal column values
Restore primary key if applied
Enable FK if applied
I am having some issues with the following cases
. When a primary key is compound (Multiple columns)
. I need to store the original FK and PK signature to allow me to restore them after the change
------- My ideas --------
Backup all_constraints and all_cons_columns records in a temporary table and after changing the column type resstoring the constraints info.
Keep with the same idea of storing the FK and PK signature to restore them after changing the column type
¿ Any suggestions ? would be appreaciate it, thx!!
You could try the old CTAS then rename method:
basically:
create new table as select c1,c1,c3 ... from old table (include data
type transformation here;
establish any indexes, constraints ...
drop old table (may need to disable donstraints first)
rename new table to old table

H2: Adding a NOT NULL column to a table with records

I'd like to add a NOT NULL column to a table called server. Problem is, the table already contains records. When I invoke ALTER TABLE server ADD COLUMN full_discovery_duration BIGINT NOT NULL H2 complains that full_discovery_duration may not be null. I can work around the problem by specifying DEFAULT 0 but I don't want a default valuefor future inserts. What am I supposed to do?
Should I add the column with a default and then remove DEFAULT 0 from the column definition in a subsequent statement? Is there a better way?
You can first add the column with a default value, and then set the default to null. Getting rid of the default definition is not possible however as far as I know.
An alternative is to first allow null, then set the values, and later not allow nulls.
drop table server;
create table server(id int);
insert into server values(1);
alter table server
add column
full_discovery_duration bigint;
update server set full_discovery_duration = 0;
alter table server
alter column
full_discovery_duration set not null;
While adding columns to existing tables, it should either be a nullable column or a default value must be specified. And what do you mean by removing the default? how can you remove value from a not null column?

Assign auto-incrementing value to new column in Oracle

I have this table in an Oracle DB which has a primary key defined on 3 of the data columns. I want to drop the primary key constraint to allow rows with duplicate data for those columns, and create a new column, 'id', to contain an auto-incrementing integer ID for these rows. I know how to create a sequence and trigger to add an auto-incrementing ID for new rows added to the table, but is it possible to write a PL/SQL statement to add unique IDs to all the rows that are already in the table?
Once you have created the sequence:
update mytable
set id = mysequence.nextval;
If you're just using an integer for a sequence you could update the id with the rownum. e.g.
update
table
set id = rownum
You then need to reset the sequence to the next valid id.
Is this what you need?
UPDATE your_table
SET id = your_seq.nextval;
This assumes you don't care what order your primary keys are in.
First you should check your PCTFREE... is there enough room for every row to get longer?
If you chose a very small PCTFREE or your data has lots of lenght-increasing updates, you might begin chaining every row to do this as an update.
You almost certainly better to do this as a CTAS.
Create table t2 as select seq.nextval, t1.* from t1.
drop t1
rename t2 to t1.

Resources