any idea why running alter column causes column to go from “not null” to “null”? - sql-server

I am mass updating a SQL Server database. I am changing all our numeric(38,0) columns to int (yes, SQL Server scripts were created from Oracle scripts).
Using SMO and C# (I am a sw engineer), I managed to generate really nice scripts like SQL Server Management Studio would.
It all works very nicely except for one particular issue:
For a handful of tables, when I call
ALTER TABLE [myTable] ALTER COLUMN [columnA] INT
it decides to also change the column from NOT NULL to NULL. That, of course is a huge issue since I need to regenerate primary keys for most of those tables on those particular columns.
Obviously, I have plenty of options using SMO to find out which columns are primary keys and force them to be NOT NULL after or while I am updating the data type, but I am really curious as to what can be causing this.
Regards,
Eric.

Because in the absense of NOT NULL, the default is NULL.
ALTER TABLE [myTable]
ALTER COLUMN [columnA] INT NOT NULL

from ALTER TABLE (Transact-SQL)
When you create or alter a table with
the CREATE TABLE or ALTER TABLE
statements, the database and session
settings influence and possibly
override the nullability of the data
type that is used in a column
definition. We recommend that you
always explicitly define a column as
NULL or NOT NULL for noncomputed
columns.

Related

Can I drop not null constraints online in SQL Server?

I have a table with quite many rows (more than 300 000 000). I want to remove not null constraint for one of the columns by running the next SQL query while the database is still under load (since the table is big, it may take about 10 minutes):
ALTER TABLE DECLARATION
ALTER COLUMN LOCAL_REFERENCE_NUMBER VARCHAR(22) NULL WITH (ONLINE = ON);
I expect this ONLINE = ON option to ensure that the table is not locked during the update to make sure that the applications that use the database can still do it during the update.
However, the docs say that ONLINE = ON is only applicable for adding and removing indexes as well as primary key or unique constraints, i.e., as it seems from the official documentation, this option has no effect for the not null constraints.
Is it indeed the case, or the documentation is just not full? If that is the case, what is so special about dropping not null constraints that it cannot be done online?
Thank you.
As stated in commment section this operation should be metadata operation only(if no data type changes occured):
ALTER TABLE DECLARATION
ALTER COLUMN LOCAL_REFERENCE_NUMBER VARCHAR(22) NULL;
It could be verified by setting Extended Event session and observing sqlserver.compressed_alter_column_is_md_only event (SQL Server 2016+)

Is it bad to use ALTER TABLE to resize a varchar column to a larger size?

I need a simple resize of a column from VARCHAR(36) to VARCHAR(40).
If you try to use SQL Server Enterprise Manager, the script it generates is effectively creating a new table with the new structure, inserting all of the data from the existing table into it, dropping the existing table, renaming the new table, and recreating any indexes.
If you read the documentation (and many online resources including SO), you can use an ALTER statement for the resize.
Does the ALTER affect the way the data is stored in any way? Indexes? Statistics? I want to avoid performance hits because of this modification due to the fact that the table can get large.
Just use ALTER TABLE. SSMS is a bit, er, stupid sometimes
You'll need to drop and recreate dependent constraints (FK, unique, index, check etc)
However, this is only a metadata change and will be very quick for any size table (unless you also change NOT NULL to NULL or varchar to nvarchar or such)
No, ALTER TABLE (http://msdn.microsoft.com/de-de/library/ms190273.aspx) is the way how Microsoft intended to do this kind of change.
And if you do not add extra options to your command, no indexes or statistics should get harmed.
A possibility of data loss is also not given, because you are just making the column bigger.
Everything should be fine.
Changes to database structure should NEVER be made using SSMS on a porduction environment for just the reason you brought up. It can destroy performance in a large table. ALTER table is the prefered method, it is faster and it can be stored in source control as a change to push to prod after testing.
Following should be the better way to handle this
IF EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '<tablename>'
AND COLUMN_NAME = '<field>')
BEGIN
ALTER TABLE <tablename> ALTER COLUMN [<field>] varchar(xxxx) null
END
ELSE

How to add one column into existing SQL Table

I have a SQL Server table and it is located on a remote server. I can connect to it with SQL Server Management Studio but opening it takes time instead, I am doing my jobs with SQL Query window without reaching it.
Recently I've made a change on the local copy of this table and want to update the remote one as well. All I've done is adding one more column which is Nullable and I'd like to learn how to add this one more column to the remote SQL Server with T-SQL without ruining the remote one data.
Here is the additional info:
Table Name: Products
Columns to be added: LastUpdate, Nullable and varchar(200)
Thanks.
The syntax you need is
ALTER TABLE Products ADD LastUpdate varchar(200) NULL
This is a metadata only operation
What about something like:
Alter Table Products
Add LastUpdate varchar(200) null
Do you need something more complex than this?
Its work perfectly
ALTER TABLE `products` ADD `LastUpdate` varchar(200) NULL;
But if you want more precise in table then you can try AFTER.
ALTER TABLE `products` ADD `LastUpdate` varchar(200) NULL AFTER `column_name`;
It will add LastUpdate column after specified column name (column_name).
alter table table_name add field_name (size);
alter table arnicsc add place number(10);

How to remove identity column from table

I have created a table with employee id as identity column. Now, I want to remove identity and replace datatype as bigint. I am using Sql Compact edition. How to achieve this?
I don't believe you can, using TSQL, remove the IDENTITY property from a column.
Instead:
Add a new BIGINT column to the table
Copy the data from the current IDENTITY field into the new field
Drop the existing column
Rename the new column to the correct name
You can do it in SSMS in the Design view for the table. I believe behind the scenes it does something like above.
Update:
To confirm, in SSMS 2K8 when you try to remove the IDENTITY property from a column and then save it, it will actually recreate the table (you can see what it does exactly by monitoring in SQL Profiler). In order to do it in SSMS, you need to ensure you have the "Prevent saving changes that require table re-creation" option turned OFF in Tools-> Options -> Designers -> Table and Database Designers. I think it defaults to ON, which would result in an error message when you try to do it otherwise.
In "real" SQL Server, you'd have to do these steps - not sure if SQL Server CE allows the same, but give it a try! I'm assuming you probably have your PRIMARY KEY constraint on that column, too - right? If not, you don't need to do the first and last step. And I'm assuming you want to have the IDENTITY on the column again, right?
-- DROP the primary key constraint (if you have that on your column)
ALTER TABLE dbo.Employees
DROP CONSTRAINT PK__Employees__3214EC274222D4EF
-- ALTER the datatype into BIGINT
ALTER TABLE dbo.Employees
ALTER COLUMN Employee_ID BIGINT
-- set PK constraint again
ALTER TABLE dbo.Employees
ADD CONSTRAINT PK_Employees PRIMARY KEY(Employee_ID)
This should help - http://www.sqlmag.com/Files/23/22081/Listing_03.txt

Can you add identity to existing column in sql server 2008?

In all my searching I see that you essentially have to copy the existing table to a new table to chance to identity column for pre-2008, does this apply to 2008 also?
thanks.
most concise solution I have found so far:
CREATE TABLE Test
(
id int identity(1,1),
somecolumn varchar(10)
);
INSERT INTO Test VALUES ('Hello');
INSERT INTO Test VALUES ('World');
-- copy the table. use same schema, but no identity
CREATE TABLE Test2
(
id int NOT NULL,
somecolumn varchar(10)
);
ALTER TABLE Test SWITCH TO Test2;
-- drop the original (now empty) table
DROP TABLE Test;
-- rename new table to old table's name
EXEC sp_rename 'Test2','Test';
-- see same records
SELECT * FROM Test;
we cannot add identity to an existing column using sql command but we can do it using GUI.
Right click on the table - design - select the column on which you want to add identity.
go to the properties available below. find the identity specification and set it to yes.
save the table.
if it is not saved the go to tools from the menu - options - table designer - uncheck the checkbox prevent saving changes. now you can save the table modifications.
now your existing table had identity.
In all of the new feature documents I read about 2008, adding identity to an existing column was not a feature I recall. The solution you've found is correct and I think the process of adding identity increment to a column automatically would be only rarely useful.
Well you can do something like this.
ALTER TABLE my_table ADD ID_COLUMN INT IDENTITY (1,1) NOT NULL
You can add the IDENTITY property to an existing column using the GUI of Enterprise Manager / Management Studio.
In SQL 2005 and earlier, you could not modify an existing column to become an identity column. I deem it very very unlikely that MS changed that in 2008.

Resources