Altering SQLite column type and adding PK constraint - sql

How to change the type of a column in a SQLite table?
I've got:
CREATE TABLE table(
id INTEGER,
salt TEXT NOT NULL UNIQUE,
step INT,
insert_date TIMESTAMP
);
I'd like to change salt's type to just TEXT and id's type to INTEGER PRIMARY KEY.

Below is an excerpt from the SQLite manual discussing the ALTER TABLE command (see URL: SQLite Alter Table):
SQLite supports a limited subset of
ALTER TABLE. The ALTER TABLE command
in SQLite allows the user to rename a
table or to add a new column to an
existing table. It is not possible to
rename a colum, remove a column, or
add or remove constraints from a
table.
As the manual states, it is not possible to modify a column's type or constraints, such as converting NULL to NOT NULL. However, there is a work around by
copying the old table to a temporary table,
creating a new table defined as desired, and
copying the data from the temporary table to the new table.
To give credit where credit is due, I learned this from the discussion on Issue #1 of hakanw's django-email-usernames project on bitbucket.org.
CREATE TABLE test_table(
id INTEGER,
salt TEXT NOT NULL UNIQUE,
step INT,
insert_date TIMESTAMP
);
ALTER TABLE test_table RENAME TO test_table_temp;
CREATE TABLE test_table(
id INTEGER PRIMARY KEY,
salt TEXT,
step INT,
insert_date TIMESTAMP
);
INSERT INTO test_table SELECT * FROM test_table_temp;
DROP TABLE test_table_temp;
Notes
I used the table name test_table since SQLite will generate an error if you try to name a table as table.
The INSERT INTO command will fail if your data does not conform to the new table constraints. For instance, if the original test_table contains two id fields with the same integer, you will receive an "SQL error: PRIMARY KEY must be unique" when you execute the "INSERT INTO test_table SELECT * FROM test_table_temp;" command.
For all testing, I used SQLite version 3.4.0 as included as part of Python 2.6.2 running on my 13" Unibody MacBook with Mac OS X 10.5.7.

Since RDBMS is not specified, these are DB2 queries:
Make ID as primary key:
ALTER TABLE table
ADD CONSTRAINT pk_id
PRIMARY KEY (id)
Make salt as not UNIQUE:
ALTER TABLE table
DROP UNIQUE <salt-unique-constraint-name>
Make salt nullable:
ALTER TABLE table
ALTER COLUMN salt DROP NOT NULL
You will need to do a reorg after drop not null. This is to be done from the command prompt.
reorg table <tableName>

In this case you can make salt to nullable and remove unique constraint. Also If id column does not contain any null or duplicate values you can safely make it primary key using sql server management studio. below is the screen shot. hope it makes it clearer:
alt text http://img265.imageshack.us/img265/7418/91573473.png
or use following sql:
alter table <TableName> modify salt text null
alter table <TableName> drop constraint <Unique Constraint Name>
alter table <TableName> modify id int not null
alter table <TableName> add constraint pk<Table>d primary key (id)

Related

Autogenerated timestamp column( primary key) to existing table DB2

Is it possible to add an autogenerated primary key column ( timestamp) to the existing table with alter table?
Something like this but it doesn't compile
ALTER TABLE DB2ADMIN.xxxyyyy ADD COLUMN ID TIMESTAMP NOT NULL WITH DEFAULT timestamp(generate_unique())#
Error during Prepare
42601(-104)[IBM][CLI Driver][DB2/AIX64] SQL0104N An unexpected token "timestamp" was found following "OT NULL WITH DEFAULT". Expected tokens may include: "CHECK". SQLSTATE=42601
It is unwise to use a fake (from generate_unique) timestamp datatype as a primary key because it makes setting values for pre-existing rows more awkward, and makes date arithmetic impossible.
The datatype TIMESTAMP is better suited for real dates/times because then you can use date arithmetic, which is practical for business. If the values in your fake timestamp-column are from generate-unique then you cannot sensibly use date arithmetic.
If you try to use a real timestamp value , (instead of generate_unique) , such as current timestamp then you are likely to get collisions, depending on the insert-rate. Usually that's a bad idea. Also this makes setting values for any pre-existing rows more difficult.
It is usually much easier and faster to use an autogenerated identity column as a surrogate primary key, especially if the table already has existing data.
Here is a typical way to do this which works with Db2-LUW and also on older versions of Db2. Other ways are possible with later versions of Db2.
Firs you need to verify that the table does not already have a primary key, as there can only be at most one of these per table.
Next, check if the table already has a unique index on a NOT NULL column, because if such a column exists then it can be promoted to be the primary key column.
If neither of the above exist, then you can use logic like this below to add an autgenerated column, set unique values in any existing rows, and ensure that any future inserts automatically get a unique value in the column without application intervention.
alter table myschema.mytab add column id bigint not null default 0 ;
alter table myschema.mytab alter column id drop default ;
alter table myschema.mytab alter column id set generated always as identity ;
update myschema.mytab set id = default ;
alter table myschema.mytab add constraint pkey primary key(id) ;
reorg table myschema.mytab ;
runstats on table myschema.mytab with distribution and detailed indexes all;
You can use CURRENT_TIMESTAMP instead of timestamp(generate_unique())
ALTER TABLE sellers ADD COLUMN ID TIMESTAMP NOT NULL WITH DEFAULT CURRENT_TIMESTAMP
You can test here

SQL Server Change Primary Key Data Type

I am working on SQL Server 2012:
I have a table with a primary key column as INT. I need to change this to a GUID.
Do I alter the table and remove int column as primary key?
Add the GUID column and set it as Primary and drop the old INT column?
Thank you.
You can't change primary key column,unless you drop it..Any operations to change its data type will lead to below error..
The object 'XXXX' is dependent on column 'XXXX'.
Only option is to
1.Drop primary key
2.change data type
3.recreate primary key
ALTER TABLE t1
DROP CONSTRAINT PK__t1__3213E83F88CF144D;
GO
alter table t1
alter column id varchar(10) not null
alter table t1 add primary key (id)
From 2012,there is a clause called (DROP_EXISTING = ON) which makes things simple ,by dropping the clustered index at final stage and also keeping old index available for all operations..But in your case,this clause won't work..
So i recommend
1.create new table with desired schema and indexes,with different name
2.insert data from old table to new table
3.finally at the time of switch ,insert data that got accumulated
4.Rename the table to old table name
This way you might have less downtime
You can change the date type of the primary key in three steps
Step 1 :- Drop the constraint associated with the Primary key
ALTER TABLE table_name
DROP CONSTRAINT constraint_name;
Step 2 :- Alter the Primay key column to a valid primary key data type
ALTER TABLE table_name
ALTER COLUMN pk_column_name target_data_type(size) not null;
Step 3 :- Make the altered column primary key again
ALTER TABLE table_name
ADD PRIMARY KEY (pk_column_name);
PS :-
You can get the Constraint name from the error message when you try to alter the
pk_column
If you already have data in the pk_column make sure the source and target data type of the column both can be used for the existing data. else another two steps would be needed to move the existing data to a temporary column and then perform the steps and bring back that data after vetting and dropping that temporary column.
Below is a script I wrote to help us deploy a change to primary key column data type.
This script assumes there aren't any non-primary key constraints (e.g. foreign keys) depending on this column.
It has a few safety checks as this was designed to be deployed to different servers (dev, uat, live) without creating side effects if the table was somehow different on a server.
I hope this helps someone. Please let me know if you find anything wrong before down-voting. I'm more than happy to update the script.
IF EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C WITH (NOLOCK) WHERE C.TABLE_CATALOG = '<<DB>>' AND C.TABLE_SCHEMA = 'dbo' AND C.TABLE_NAME = '<<Table>>'
AND C.COLUMN_NAME = '<<COLUMN>>' AND C.DATA_TYPE = 'int') -- <- Additional test to check the current datatype so this won't make unnecessary or wrong updates
BEGIN
DECLARE #pkName VARCHAR(200);
SELECT #pkName = pkRef.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS pkRef WITH (NOLOCK)
WHERE pkRef.TABLE_CATALOG = '<<DB>>' AND pkRef.TABLE_SCHEMA = 'dbo' AND TABLE_NAME = '<<Table>>'
IF(#pkName IS NOT NULL)
BEGIN
-- Make sure the primary key name is the one you are going to use in script beyond this point.
IF(#pkName != '<<PRIMARY KEY NAME>>')
BEGIN
RAISERROR ('Unexpected primary key name - The primary key found has a different name than expected. Please update the script.', 16, 1);
RETURN;
END
ALTER TABLE dbo.<<Table>>
DROP CONSTRAINT <<PRIMARY KEY NAME>>; -- Note: this is not a string or a variable (just type the PK name)
SELECT 'Dropped existing primary key';
END
ALTER TABLE dbo.<<Table>> ALTER COLUMN ID BIGINT
SELECT 'Updated column type to big int';
ALTER TABLE dbo.<<Table>>
ADD CONSTRAINT <<PRIMARY KEY NAME>> PRIMARY KEY CLUSTERED (<<COLUMN>>);
SELECT 'Created the primary key';
END
ELSE
BEGIN
SELECT 'No change required.';
END
In case other tables reference your PK with indexed FK's, these are the steps you must follow.
In this example, the main table's called Main, the single referencing table Reference. I'm changing the datatype to NVARCHAR(7). To use it:
Find/replace all these table names with your own;
Modify the data type;
You might also need to separately find/replace the dbo schema;
I'm using syntax which includes constraint names - if you want, also update these to your preferred naming conventions.
ALTER TABLE dbo.Main ADD IdNew NVARCHAR(7);
UPDATE dbo.Main SET IdNew = Id;
-- For all tables with FK's to this Main:
ALTER TABLE dbo.Reference ADD MainIdNew NVARCHAR(7);
UPDATE dbo.Reference SET MainIdNew = MainId;
ALTER TABLE dbo.Reference DROP CONSTRAINT FK_Reference_MainId_Main_Id;
DROP INDEX IX_Reference_MainId ON dbo.Reference;
ALTER TABLE dbo.Reference DROP COLUMN MainId;
-- Until here
ALTER TABLE dbo.Main DROP CONSTRAINT PK_Main;
ALTER TABLE dbo.Main DROP COLUMN Id;
EXEC sp_rename 'dbo.Main.IdNew', 'Id', 'COLUMN';
ALTER TABLE dbo.Main ALTER COLUMN Id NVARCHAR(7) NOT NULL;
ALTER TABLE dbo.Main ADD CONSTRAINT PK_Main PRIMARY KEY (Id);
-- Again for all tables with FK's to this Main:
EXEC sp_rename 'dbo.Reference.MainIdNew', 'MainId', 'COLUMN';
ALTER TABLE dbo.Reference ADD CONSTRAINT FK_Reference_MainId_Main_Id FOREIGN KEY (MainId) REFERENCES dbo.Main(Id);
CREATE INDEX IX_Reference_MainId ON dbo.Reference(MainId);
Right in the table you want to change the PK type >> Modify. Go in the column, change the type and save. If you want to see the code for such a change, before saving, you can right-click >> "Generate Change Script ..".
Using Microsoft SQL Server Management Studio do the following:
Open table Design
Change the primary key column type or any other change which is also possible with this way
Right click on the design area and select Generate Change Script
Accept Validation Warning
Preview changes or save them in file.
Profit :)
This works for any change to the table, just bare in mind that SSMS creates a temporary second table to do the difficult changes like primary column type change.
This works for me in version 18.9 of the app.

Altering my primary key to auto increment - JavaDB

I am using Netbeans, writing in Java and using Derby.
I have a table within APP called PERSON. Within PERSON I have a column called PID with the following properties:
Name: PID
Nulls allowed: [ ]
Data type: NUMERIC
Column size: 4
Decimal digits: 0
Position: 1
Part of a primary key: [/]
Part of an index: [/]
I used the meta data isAutoIncrement function to check if it was already auto incrementing and it is not!
I have since tried using the following SQL commands to alter it:
I believe this may not have been for Derby:
ALTER TABLE APP.PERSON ALTER PID NOT NULL PRIMARY KEY GENERATED ALWAYS AS IDENTITY
(START WITH 1, INCREMENT BY 1);
Upon checking the Oracle website, I found the correct syntax:
ALTER TABLE APP.PERSON ALTER PID SET INCREMENT BY 1;
I even tried leading zeros:
ALTER TABLE APP.PERSON ALTER PID SET INCREMENT BY 0001;
None of which have worked, the error I get on the last two are:
ALTER TABLE '"APP"."PERSON"' specified attributes for column 'PID' that are
not compatible with the existing column.
Any ideas of the correct syntax?
Here's what I generally do to accomplish this:
Create a new table, with the desired schema, including the generated primary key
Issue a INSERT INTO newtable SELECT columns FROM oldtable to populate the new table's data from the old table
Rename the old table to some temporary name, like table_soon_to_be_deleted
Rename the new table to the desired table name
Do some testing to make sure that my behavior is as expected
Drop the old table that I renamed in step (4).
JavaDB does not allow altering a column with generated key word so I found the best way is to recreate the table and specify the primary key as auto incremented. For example;
create table staff(
ID int primary key always generated as identity,
name varchar(100)
);
This worked for me.

How to add a PK to an existing table in DB2?

I am facing one problem. I have a table already create in DB2.
CREATE TABLE "DDL12"
(
"D4_1" decimal(10,0),
"D4_2" decimal(10,0),
);
I am trying to create a PK on this table as :-
ALTER TABLE "DDL12" ADD CONSTRAINT "Key4" PRIMARY KEY ("D4_1");
But while running the command, I am getting the error saying D4_1 is NULLABLE.
Now, how can I create a PK on this table?
Thanks
Yes, this is due the fact, that your database "could have" rows having NULL value in that non PK column right now.
So first set the column to NOT NULL (+ make sure having a unique value in all rows) and then set the primary key with the command above.
You can change a column to not NULL like this:
ALTER TABLE "DDL12"
MODIFY "D4_1" decimal(10,0) NOT NULL;

How do I add a auto_increment primary key in SQL Server database?

I have a table set up that currently has no primary key. All I need to do is add a primary key, no null, auto_increment.
I'm working with a Microsoft SQL Server database. I understand that it can't be done in a single command but every command I try keeps returning syntax errors.
edit ---------------
I have created the primary key and even set it as not null. However, I can't set up the auto_increment.
I've tried:
ALTER TABLE tableName MODIFY id NVARCHAR(20) auto_increment
ALTER TABLE tableName ALTER COLUMN id NVARCHAR(20) auto_increment
ALTER TABLE tableName MODIFY id NVARCHAR(20) auto_increment
ALTER TABLE tableName ALTER COLUMN id NVARCHAR(20) auto_increment
I'm using NVARCHAR because it wouldn't let me set NOT NULL under int
It can be done in a single command. You need to set the IDENTITY property for "auto number":
ALTER TABLE MyTable ADD mytableID int NOT NULL IDENTITY (1,1) PRIMARY KEY
More precisely, to set a named table level constraint:
ALTER TABLE MyTable
ADD MytableID int NOT NULL IDENTITY (1,1),
CONSTRAINT PK_MyTable PRIMARY KEY CLUSTERED (MyTableID)
See ALTER TABLE and IDENTITY on MSDN
If the table already contains data and you want to change one of the columns to identity:
First create a new table that has the same columns and specify the primary key-kolumn:
create table TempTable
(
Id int not null identity(1, 1) primary key
--, Other columns...
)
Then copy all rows from the original table to the new table using a standard insert-statement.
Then drop the original table.
And finally rename TempTable to whatever you want using sp_rename:
http://msdn.microsoft.com/en-us/library/ms188351.aspx
You can also perform this action via SQL Server Management Studio.
Right click on your selected table -> Modify
Right click on the field you want to set as PK --> Set Primary Key
Under Column Properties set "Identity Specification" to Yes, then specify the starting value and increment value.
Then in the future if you want to be able to just script this kind of thing out you can right click on the table you just modified and select
"SCRIPT TABLE AS" --> CREATE TO
so that you can see for yourself the correct syntax to perform this action.
If you have the column it's very easy.
Using the designer, you could set the column as an identity (1,1): right click on the table → design → in part left (right click) → properties → in identity columns, select #column.
Properties:
Identity column:
In SQL Server 2008:
Right click on table
Go to design
Select numeric datatype
Add Name to the new column
Make Identity Specification to 'YES'
you can try this...
ALTER TABLE Your_Table
ADD table_ID int NOT NULL PRIMARY KEY auto_increment;