Alter table in database throwing error in SQL Developer - sql

I have the following query to alter my customer table to add a column for checking if a customer is active or not.
ALTER TABLE COMPANY.CUSTOMER
ADD (isActive VARCHAR2(18 CHAR) DEFAULT 'FALSE' NOT NULL)
CHECK(isActive in ('TRUE','FALSE'));
I get the following error:
RA-01735: invalid ALTER TABLE option
01735. 00000 - "invalid ALTER TABLE option"
I tried to change the order and still did not work. can you help me with why it is failing to alter the table?
Also how to ensure if TRUE or FALSE is always uppercase when inserting?

You can split up the CHECK constraint from the ADD COLUMN for one route...
/* drop table customer_so purge; */
create table customer_so (id integer, name varchar2(50));
ALTER TABLE CUSTOMER_SO
ADD (ISACTIVE VARCHAR2(20) DEFAULT 'FALSE' );
ALTER TABLE CUSTOMER_SO
ADD CONSTRAINT CUSTOMER_SO_CHK1 CHECK
(ISACTIVE IN ('TRUE', 'FALSE'))
ENABLE;
Or, like you had, all in one go -
/* drop table customer_so purge; */
create table customer_so (id integer, name varchar2(50));
ALTER TABLE CUSTOMER_SO
ADD (ISACTIVE VARCHAR2(20) DEFAULT 'FALSE' constraint CUSTOMER_SO_CHK1 CHECK
(ISACTIVE IN ('TRUE', 'FALSE')));
So basically end of the day, you're missing the 'CONSTRAINT' keyword.
Since you tagged oracle-sqldeveloper, you should know the EDIT TABLE ddialog lets you click through these changes, and will generate the DDL for you -
Finally, by default, strings in Oracle are case-sensitive, so your check constraint will work as desired.

Related

Postgres breaking null constraint on a serial column

I have a table that I create independently, the primary key is set with the serial type and a sequence applied to the table, but when I try to insert a value a NULL CONSTRAINT error is thrown and the return looks like null was passed, am I missing something in the INSERT statement?
SQL for table generation:
DROP TABLE IF EXISTS public."Team" CASCADE;
CREATE TABLE public."Team" (
"IdTeam" serial PRIMARY KEY,
name text NOT null,
CONSTRAINT "pKeyTeamUnique" UNIQUE ("IdTeam")
);
ALTER TABLE public."Team" OWNER TO postgres;
DROP SEQUENCE IF EXISTS public."Team_IdTeam_seq" CASCADE;
CREATE SEQUENCE public."Team_IdTeam_seq"
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE public."Team_IdTeam_seq" OWNER TO postgres;
ALTER SEQUENCE public."Team_IdTeam_seq" OWNED BY public."Team"."IdTeam";
SQL for insert :
INSERT INTO public."Team" (name) values ('Manchester Untited');
The returning error:
ERROR: null value in column "IdTeam" violates not-null constraint
DETAIL: Failing row contains (null, Manchester Untited).
SQL state: 23502
I am baffled. Why are you trying to define your own sequence when the column is already defined as serial?
Second, a primary key constraint is already unique. There is no need for a separate unique constraint.
Third, quoting identifiers just makes the code harder to write and to read.
You can just do:
DROP TABLE IF EXISTS public.Team CASCADE;
CREATE TABLE public.Team (
IdTeam serial PRIMARY KEY,
name text NOT null
);
INSERT INTO public.Team (name)
VALUES ('Manchester Untited');
Dropping the sequence causes the default definition for the IdTeam column to be dropped. After recreating the sequence you will have to recreate the default definition.

DB2 add auto increment column to an existing table

I have a table with following schema in my DB2 database.
CREATE TABLE IDN_OAUTH_CONSUMER_APPS (
CONSUMER_KEY VARCHAR (255) NOT NULL,
CONSUMER_SECRET VARCHAR (512),
USERNAME VARCHAR (255),
TENANT_ID INTEGER DEFAULT 0,
APP_NAME VARCHAR (255),
OAUTH_VERSION VARCHAR (128),
CALLBACK_URL VARCHAR (1024),
GRANT_TYPES VARCHAR (1024)
/
I need to add a new column ID of Type integer not null auto increment, and make it the primary key. How can I do that without deleting the table?
I could do this successfully using following set of queries.
ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD COLUMN ID INTEGER NOT NULL DEFAULT 0
CREATE SEQUENCE IDN_OAUTH_CONSUMER_APPS_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
CREATE TRIGGER IDN_OAUTH_CONSUMER_APPS_TRIGGER NO CASCADE BEFORE INSERT ON IDN_OAUTH_CONSUMER_APPS REFERENCING NEW AS NEW FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET (NEW.ID) = (NEXTVAL FOR IDN_OAUTH_CONSUMER_APPS_SEQUENCE); END
REORG TABLE IDN_OAUTH_CONSUMER_APPS
UPDATE IDN_OAUTH_CONSUMER_APPS SET ID = IDN_OAUTH_CONSUMER_APPS_SEQUENCE.NEXTVAL
And then add primary key using alter table.
Use a multi-step approach:
add the column ALTER TABLE ADD... with just the integer data type and as nullable
update the table to set the intended identity values for that column
alter the table to add the auto-generation
alter the table to add the primary key on that column
You need to have multiple steps because the identity values need to be added manually. Syntax and examples for ALTER TABLE can be found here.
There is an easy way to do it. Just run the alters above:
ALTER TABLE idn_oauth_consumer_apps ADD COLUMN id INTEGER NOT NULL DEFAULT 0;
ALTER TABLE idn_oauth_consumer_apps ALTER COLUMN id SET GENERATED ALWAYS AS IDENTITY;
It is simple and fast even on big tables. Tested and working on DB2 for i V7R2.
I recommend using this approach. It does not require creating any satellite objects - no triggers, sequences, etc...
alter table test.test2 add column id integer not null default 0;
alter table test.test2 alter column id drop default;
alter table test.test2 alter column id set generated always as identity;
call sysproc.admin_cmd ('reorg table test.test2');
update test.test2 set id = default;
commit;
If using "db2" cli then the reorg command may be run directly without the "call sysproc.admin_cmd" wrapper.
Create a new table with the primary key field. Insert the records from the old table. Drop the old table and if you can, rename the new one. If you can't rename it, recreate it and populate from the one that now has the records.
Building on Chamila Wijayarathna's answer, I used the following:
ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD COLUMN ID INTEGER NOT NULL DEFAULT 0
CREATE SEQUENCE IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE START WITH 1 INCREMENT BY 1 NOCACHE
CREATE TRIGGER IDN_OAUTH_CONSUMER_APPS_ID_TRIGGER NO CASCADE BEFORE INSERT ON
IDN_OAUTH_CONSUMER_APPS REFERENCING NEW AS NEW
FOR EACH ROW MODE DB2SQL BEGIN ATOMIC SET (NEW.ID) = (NEXTVAL FOR
IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE); END
REORG TABLE IDN_OAUTH_CONSUMER_APPS
UPDATE IDN_OAUTH_CONSUMER_APPS SET ID = IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE.NEXTVAL
ALTER TABLE IDN_OAUTH_CONSUMER_APPS ADD PRIMARY KEY (ID)
REORG TABLE IDN_OAUTH_CONSUMER_APPS
Then to reverse:
REORG TABLE IDN_OAUTH_CONSUMER_APPS
ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP PRIMARY KEY
DROP TRIGGER IDN_OAUTH_CONSUMER_APPS_ID_TRIGGER
DROP SEQUENCE IDN_OAUTH_CONSUMER_APPS_ID_SEQUENCE
ALTER TABLE IDN_OAUTH_CONSUMER_APPS DROP COLUMN ID
REORG TABLE IDN_OAUTH_CONSUMER_APPS
Tried this on DB2 for z/OS v12 and it worked:
alter table TABLE_NAME add column id integer generated always as identity

How to add a new column and a constraint in one go?

I want to add a new column to an existing table.
I need it to emulate the enum type (in the way possible in SQL Server; with value constraints, that is).
The following doesn't work:
ALTER TABLE orders ADD [sent_to_panel] NVARCHAR(16) NULL;
ALTER TABLE orders WITH CHECK ADD CONSTRAINT [CK_orders] CHECK (([sent_to_panel]='invalidated' OR [sent_to_panel]='not_sent' OR [sent_to_panel]='sent'));
ALTER TABLE orders ADD CONSTRAINT [DF_orders_sent_to_panel] DEFAULT (N'not_sent') FOR [sent_to_panel];
ALTER TABLE orders CHECK CONSTRAINT [CK_orders];
I'm getting an error:
Msg 207, Level 16, State 1, Line 2
Invalid column name 'sent_to_panel'.
If I execute the first command on its own, though:
ALTER TABLE orders ADD [sent_to_panel] NVARCHAR(16) NULL;
The rest goes through.
So I suppose the problem is that the column isn't actually added yet (and thus not recognized by ADD CONSTRAINT) when trying to get it all done in one go.
The question is: how to make the script work properly?
CREATE TABLE a (
b int
);
ALTER TABLE a
ADD c nvarchar(16) NULL
, CONSTRAINT check_this CHECK (c IN ('invalidated', 'not_sent', 'sent'))
, CONSTRAINT defaultify DEFAULT ('not_sent') FOR c
;
ALTER TABLE a
CHECK CONSTRAINT check_this
;
DROP TABLE a;

How to modify datatype of a column with a default value

I'm trying to change the datatype of a column in SQL Server from tinyint to smallint.
But there's a default value on my column and I don't know the name of the constraint.
Is there an easy way to do it ?
This don't work because of the default constraint :
ALTER TABLE mytable
Alter Column myColumn smallint NOT NULL default 1
You need to do this in several steps - first: drop the default constraint on your column, then modify your column.
You could use code something like this:
-- find out the name of your default constraint -
-- assuming this is the only default constraint on your table
DECLARE #defaultconstraint sysname
SELECT #defaultconstraint = NAME
FROM sys.default_constraints
WHERE parent_object_id = object_ID('dbo.mytable')
-- declare a "DROP" statement to drop that default constraint
DECLARE #DropStmt NVARCHAR(500)
SET #DropStmt = 'ALTER TABLE dbo.mytable DROP CONSTRAINT ' + #defaultconstraint
-- drop the constraint
EXEC(#DropStmt)
-- alternatively: if you *know* the name of the default constraint - you can do this
-- more easily just by executing this single line of T-SQL code:
-- ALTER TABLE dbo.mytable DROP CONSTRAINT (fill in name of constraint here)
-- modify the column's datatype
ALTER TABLE dbo.mytable
Alter Column myColumn smallint NOT NULL
-- re-apply a default constraint - hint: give it a sensible name!
ALTER TABLE dbo.mytable
ADD CONSTRAINT DF_mytable_myColumn DEFAULT 1 FOR MyColumn
You could do it as a three step process
add the new column with a different name,
copy the values from the old column to the new
drop the old column
It it matters that the name is the same, then repeat the process to change the name back.
You can find the constraint name for the default using MS Management Studio. Just find the tables folder for the given DB and look under Constraints. If there are many constraints, you can "Script the Constraint(s) to a query window which show the associated column name.

In SQL Server 2005, how do I set a column of integers to ensure values are greater than 0?

This is probably a simple answer but I can't find it. I have a table with a column of integers and I want to ensure that when a row is inserted that the value in this column is greater than zero. I could do this on the code side but thought it would be best to enforce it on the table.
Thanks!
I was in error with my last comment all is good now.
You can use a check constraint on the column. IIRC the syntax for this looks like:
create table foo (
[...]
,Foobar int not null check (Foobar > 0)
[...]
)
As the poster below says (thanks Constantin), you should create the check constraint outside the table definition and give it a meaningful name so it is obvious which column it applies to.
alter table foo
add constraint Foobar_NonNegative
check (Foobar > 0)
You can get out the text of check constraints from the system data dictionary in sys.check_constraints:
select name
,description
from sys.check_constraints
where name = 'Foobar_NonNegative'
Create a database constraint:
ALTER TABLE Table1 ADD CONSTRAINT Constraint1 CHECK (YourCol > 0)
You can have pretty sophisticated constraints, too, involving multiple columns. For example:
ALTER TABLE Table1 ADD CONSTRAINT Constraint2 CHECK (StartDate<EndDate OR EndDate IS NULL)
I believe you want to add a CONSTRAINT to the table field:
ALTER TABLE tableName WITH NOCHECK
ADD CONSTRAINT constraintName CHECK (columnName > 0)
That optional NOCHECK is used to keep the constraint from being applied to existing rows of data (which could contain invalid data) & to allow the constraint to be added.
Add a CHECK constraint when creating your table
CREATE TABLE Test(
[ID] [int] NOT NULL,
[MyCol] [int] NOT NULL CHECK (MyCol > 1)
)
you can alter your table and add new constraint like bellow.
BEGIN TRANSACTION
GO
ALTER TABLE dbo.table1 ADD CONSTRAINT
CK_table1_field1 CHECK (field1>0)
GO
ALTER TABLE dbo.table1 SET (LOCK_ESCALATION = TABLE)
GO
COMMIT