How enable Incremental Statistics by alter table - sql-server

to enable incremental update statistics i have to create partition function, partition scheme, index on my table and create table in this way
create table [tmp].[PartitionTest]
(
[RecordId] int not null
,[CreateDate] datetime
,[Quantity] int
) on [ups_partionByDate_scheme226] ([CreateDate])
But, when I can't create table like and add this line
on [ups_partionByDate_scheme226] ([CreateDate])
Can I do this by alter table or other way?

Yes.
If your table has a clustered index, then you need to drop it and after that you can use the following code snippet. If you have no cluster index, skip the previous sentence.
ALTER TABLE [tmp].[PartitionTest] ADD CONSTRAINT [PK_ParitionTest_CreateDate] PRIMARY KEY CLUSTERED
(
[CreateDate]
) ON [ups_partionByDate_scheme226] ([CreateDate]);
See also Create Partitioned Tables and Indexes

Related

SQL Server 2012 Create unique index with constraint on table creation

I'm using database projects in Visual Studio and I'm looking to make a unique index with a where clause on table creation, rather than having to create the table and add another script to add the constraint to the index. My constraint is
CREATE UNIQUE NONCLUSTERED INDEX ix_IdNotNull
ON MyTable(MyId)
WHERE MyId IS NOT NULL;
I'm looking for something like
create table MyTable
(
MyId int unique where MyId is not null
)
but SSMS doesn't like this. Is it possible to assign a where clause to a unique constraint when the table is created?
Add NC UNIQUE index
For sql 2016 +
create table MyTable
(
MyId int ,
INDEX [i_MyTable] UNIQUE NONCLUSTERED (MyId) WHERE [MyId] IS NOT NULL
)
early version
CREATE UNIQUE NONCLUSTERED INDEX [i_MyTable]
ON [MyTable] (MyId)
WHERE [MyId] IS NOT NULL

How do I change a column from null to not null when an index depends on that column without recreating the index?

I have a column Column which is declared to be NULL DEFAULT(GETUTCDATE()) and there's a non-clustered index that includes this column. I want to change this column to be NOT NULL DEFAULT(GETUTCDATE()) and when I run ALTER TABLE ALTER COLUMN statement the SQL Azure service says it cannot change the column because there's an index depending on this column.
That's a production database and the table holds about ten million records. So I'd rather not drop and recreate the index because that would slow down the database (especially creating the index can take minutes).
How can I change the column without recreating the index?
Table column does not have to be altered to enforce NOT NULL. Instead a new constraint can be added to the table:
ALTER TABLE [Table] WITH CHECK
ADD CONSTRAINT [TableColumnNotNull] CHECK ([Column] Is NOT NULL);
That would not affect the index but the optimizer would use this constraint to improve performance:
CREATE TABLE Test (ID bigint PRIMARY KEY, [Column] DATE NULL DEFAULT(GETUTCDATE()));
GO --< Create test table
CREATE NONCLUSTERED INDEX TestColumnIdx ON Test ([Column]);
GO --< Create the index
ALTER TABLE Test ALTER COLUMN [Column] DATE NOT NULL;
GO --< That won't work: the index 'TestColumnIdx' is dependent on column 'Column'
Select * From Test Where [Column] Is NULL;
GO --< Check the plan: it has "Index Seek (NonClustered)"
ALTER TABLE Test WITH CHECK ADD CONSTRAINT TestColumnNotNull CHECK ([Column] Is NOT NULL);
GO --< Add a "stand-alone" NOT NULL constraint
Select * From Test Where [Column] Is NULL;
GO --< Check the plan: it has "Constant Scan" now
DROP TABLE Test;
GO --< Clean-up

New uniqueidentifier on the go

I want to add a column for a table which would become a PRIMARY KEY and be of type uniqueidentifier. I have this, but I wonder if there is a faster (in fewer code lines) way?
ALTER TABLE [table] ADD [id] [uniqueidentifier]
DEFAULT('00000000-0000-0000-0000-000000000000') NOT NULL
GO
UPDATE [table] SET [id] = NEWID()
GO
ALTER TABLE [table] ADD CONSTRAINT [PK_table_id] PRIMARY KEY CLUSTERED
GO
If you want to keep naming your constraints (and you should), I don't think we can reduce it below 2 statements:
create table T (
Col1 varchar(10) not null
)
go
insert into T (Col1)
values ('abc'),('def')
go
ALTER TABLE T ADD [id] [uniqueidentifier] constraint DF_T_id DEFAULT(NEWID()) NOT NULL
GO
ALTER TABLE T ADD constraint PK_T PRIMARY KEY CLUSTERED (id)
go
drop table T
Note, that I've added a name for the default constraint. Also, this ensures that new rows also have id values assigned. As I said in my comment, it's usually preferable to avoid having columns with values generated by NEWID() clustered - it leads to lots of fragmentation. If you want to avoid that, consider NEWSEQUENTIALID().
If you don't care about constraint names, you can do it as a single query:
ALTER TABLE T ADD [id] [uniqueidentifier] DEFAULT(NEWID()) NOT NULL PRIMARY KEY CLUSTERED

Add primary key column in SQL table

I am student of RDBMS.
I have very basic question let say I have one existing Table in SQL server. What will be script to alter table.
Drop Column 'RowId' if exist.
Drop contraint if exist.
Add one new column 'RowId' into table.
Make this column as primary key.
Autoincrement type int.
In SQL Server 2005 or newer, you could use this script:
-- drop PK constraint if it exists
IF EXISTS (SELECT * FROM sys.key_constraints WHERE type = 'PK' AND parent_object_id = OBJECT_ID('dbo.YourTable') AND Name = 'PK_YourTable')
ALTER TABLE dbo.YourTable
DROP CONSTRAINT PK_YourTable
GO
-- drop column if it already exists
IF EXISTS (SELECT * FROM sys.columns WHERE Name = 'RowId' AND object_id = OBJECT_ID('dbo.YourTable'))
ALTER TABLE dbo.YourTable DROP COLUMN RowId
GO
-- add new "RowId" column, make it IDENTITY (= auto-incrementing)
ALTER TABLE dbo.YourTable
ADD RowId INT IDENTITY(1,1)
GO
-- add new primary key constraint on new column
ALTER TABLE dbo.YourTable
ADD CONSTRAINT PK_YourTable
PRIMARY KEY CLUSTERED (RowId)
GO
Of course, this script may still fail, if other tables are referencing this dbo.YourTable using foreign key constraints onto the pre-existing RowId column...
Update: and of course, anywhere I use dbo.YourTable or PK_YourTable, you have to replace those placeholder with the actual table / constraint names from your own database (you didn't mention what they were, in your question.....)
Note: this answer was added before questions update
Add new column (note: you can only have one IDENTITY column per table)
Drop old primary key
Add new primary key
Drop old column if needed
Sample script:
CREATE TABLE whatever (
OldPKColumn uniqueidentifier NOT NULL,
CONSTRAINT PK_whatever PRIMARY KEY (OldPKColumn)
)
ALTER TABLE whatever
ADD RowId int NOT NULL IDENTITY (1,1);
ALTER TABLE whatever
DROP CONSTRAINT PK_whatever;
ALTER TABLE whatever WITH CHECK
ADD CONSTRAINT PK_whatever PRIMARY KEY CLUSTERED (RowId);
ALTER TABLE whatever
DROP COLUMN oldPKcolumn;
And a random thought... are you trying to reset an IDENTITY column?
If so, then use DBCC CHECKIDENT
Just a comment to improve these great answers (can't use comments yet - I'm one reputation point away from that privilege) and as future reference for myself:
A new IDENTITY (autonumber) column can be added and made the primary key in a single statement as well:
ALTER TABLE [TableName] ADD [ColumnName] int IDENTITY PRIMARY KEY;
I prefer not to bother with constraint names when it doesn't help.
You can specify seed (and increment) values between parantheses after the IDENTITY keyword.

SQL Server creating table with clustered index without a primary key

Is it possible to create a clustered index from a create table statement in SQL Server 2008 that is not a primary key?
The purpose of this is for a table in SQL Azure, so it is not an option for me to first create the table, and then create the clustered index on the table.
Edit: Apparently it was FluentMigrator that was causing my problems, it's version table does not have a clustered index so it was erroring trying to create the versioning table not my table.
Yes, it is possible to create a clustered index that is not the primary key. Just use a CREATE CLUSTERED INDEX statement.
CREATE TABLE dbo.myTable (
myTableId int PRIMARY KEY NONCLUSTERED
myColumn int NOT NULL
)
CREATE CLUSTERED INDEX myIndex ON dbo.myTable(myColumn)
Prior to version Azure SQL Database v12, you had to have a clustered index before you could insert any data to a table. As of Azure SQL Database v12, heaps (tables without a clustered index) are now supported.
If your database was created prior to June 2016, here are the instructions for upgrading to version 12.
CREATE TABLE dbo.Table_1
(
Id int NOT NULL IDENTITY (1, 1) PRIMARY KEY NONCLUSTERED,
SomeOtherUniqueColumn int NOT NULL CONSTRAINT Item4 UNIQUE CLUSTERED
) ON [PRIMARY]
note the specification of nonclustered on the primary key
This will still work.
CREATE TABLE dbo.Table_1
(
SomeOtherUniqueColumn int NOT NULL CONSTRAINT Item4 UNIQUE CLUSTERED
) ON [PRIMARY]
The code below is compatible with Azure. It creates a primary key non-clustered and a clustered index in a single create table statement. This syntax also allows for specifying more than one column in your key.
CREATE TABLE MyTable (
ID uniqueidentifier NOT NULL,
UserID uniqueidentifier NOT NULL,
EntryDate DATETIME NOT NULL,
CONSTRAINT PK_MyPrimaryKey_Name PRIMARY KEY NONCLUSTERED (ID),
CONSTRAINT UCI_MyClusteredIndexName UNIQUE CLUSTERED (UserID ASC,EntryDate ASC,ID ASC)
);
In order to change a tables clustered index, the clusteredd index must be dropped, which converts the table into a heap and then the new clustered index is applied. Because Azure does not support heaps (tables without clustered indexes) it is not possible to change the clustered index without dropping the table and recreating it. In Azure you can not specify a clustered index in any other place other than the table create statement.

Resources