I'm creating an SQL setup script and I'm using someone else's script as an example. Here's an example of the script:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[be_Categories](
[CategoryID] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_be_Categories_CategoryID] DEFAULT (newid()),
[CategoryName] [nvarchar](50) NULL,
[Description] [nvarchar](200) NULL,
[ParentID] [uniqueidentifier] NULL,
CONSTRAINT [PK_be_Categories] PRIMARY KEY CLUSTERED
(
[CategoryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Does anyone know what the ON [PRIMARY] command does?
When you create a database in Microsoft SQL Server you can have multiple file groups, where storage is created in multiple places, directories or disks. Each file group can be named. The PRIMARY file group is the default one, which is always created, and so the SQL you've given creates your table ON the PRIMARY file group.
See MSDN for the full syntax.
It refers to which filegroup the object you are creating resides on. So your Primary filegroup could reside on drive D:\ of your server. you could then create another filegroup called Indexes. This filegroup could reside on drive E:\ of your server.
ON [PRIMARY] will create the structures on the "Primary" filegroup. In this case the primary key index and the table will be placed on the "Primary" filegroup within the database.
Please be aware about an important behavior related to file groups.
Using OP's SQL Script you can never mention two different file groups i.e. one for storing your data rows and the other for index data structure. This is not allowed.
This is due to the fact that the index being created in this case is a clustered Index on the column which is primary key for the table. Metadata of the clustered index and data rows of a table can never be on two different file groups.
My database has two file groups namely PRIMARY and SECONDARY. Now look at the below script. It will store the table's row data as well as clustered index data both on PRIMARY file group itself. This is happening even when I've mentioned a different file group ([SECONDARY]) for storing the table's row data.
CREATE TABLE [dbo].[be_Categories](
[CategoryID] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_be_Categories_CategoryID] DEFAULT (newid()),
[CategoryName] [nvarchar](50) NULL,
[Description] [nvarchar](200) NULL,
[ParentID] [uniqueidentifier] NULL,
CONSTRAINT [PK_be_Categories] PRIMARY KEY CLUSTERED
(
[CategoryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [SECONDARY]
GO
More interestingly, the above script runs to completion without any error(I was expecting an error as I had given two different file groups). SQL Server does the trick behind the scene silently without throwing any error.
NOTE: But yes, the index can reside on a different file group in case of non-clustered indexes.
SQL script shown below creates a non-clustered index. The non-clustered index will get created on [SECONDARY] file group while the table's data rows reside on [PRIMARY] file group:
CREATE NONCLUSTERED INDEX [IX_Categories] ON [dbo].[be_Categories]
(
[CategoryName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [Secondary]
GO
You can get more information here about how storing non-clustered indexes on a different file group can boost query performance.
Related
I have a table Log:
CREATE TABLE [dbo].[Log]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
[Date] [DATETIME] NOT NULL,
[Thread] [VARCHAR](255) NOT NULL,
[Level] [VARCHAR](50) NOT NULL,
[Logger] [VARCHAR](255) NOT NULL,
[Message] [VARCHAR](4000) NOT NULL,
[Exception] [VARCHAR](2000) NULL,
CONSTRAINT [PK_Log]
PRIMARY KEY NONCLUSTERED ([Id] ASC)
)
The PK is Id, and we partitioned column [Date] after create an index on it and change PK to non-clustered:
ALTER TABLE [dbo].[Log]
ADD CONSTRAINT [PK_Log]
PRIMARY KEY NONCLUSTERED ([Id] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
CREATE CLUSTERED INDEX [IX_Log_Date]
ON [dbo].[Log]([Date] ASC) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
The partitions are created successfully.
Now, we want to use Truncate to remove partitions:
TRUNCATE TABLE [dbo].[Log]
WITH (PARTITIONS (1 TO 2));
But get this error:
TRUNCATE TABLE statement failed. Index 'PK_Log' is not partitioned, but table 'Log' uses partition function 'myDateRangePF'. Index and table must use an equivalent partition function.
Does this mean partitioned table can only have one index? if the existing table has multiple index, in order to truncate it, we have to remove all indexes first?
Thanks
The issue is that you created the index PK_Log...ON [PRIMARY], which made it a non-partitioned index on a partitioned table. You'll need to drop that index (and any other non-partitioned indexes, probably) and recreate it. Either specify the partitioning filegroup explicitly, or leave the ON clause out and let SQL Server pick the filegroup. By default, it will create the index on the same filegroup as the underlying table and with the same partitioning as the table.
See Partitioned Indexes in BOL for additional information.
I am suffering from horrendous performance issues using a Azure Sql DB.
Its one table in particular with the following schema:
CREATE TABLE [dbo].[RawTwitter](
[Id] [int] IDENTITY(1,1) NOT NULL,
[IsError] [bit] NULL,
[ErrorDescription] [nvarchar](max) NULL,
[IsProcessed] [bit] NULL,
[IsRunResult] [bit] NULL,
[RawJson] [nvarchar](max) NULL,
The RawJson field is the culprit. If I do a SELECT that contains that field my query takes minutes - like 20 minutes! If I take that column out of the query its instant. There are only about 45,000 records in that table!
I'm not getting this issue on local so I scripted that table and found that it differed from that on Azure. On local, the following is appended to the table script:
CONSTRAINT [PK_RawTwitter] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
but on Azure version the TEXTIMAGE_ON [PRIMARY] is omitted. Having done some more digging it would appear that Azure does not allow that last keyword? And it would appear that this affects how large text fields are stored.
This would seem to be the obvious reason there is such a big difference in performance between my local and staging. What other things can I try to get around this performance nightmare?
I'm newbie level in SQL Server
I want to allow null value in column, but it can't save.
So I will re-create a new table with same structure.
Please your help to allow null value in column with SQL script.
Thank you..
It looks as though the designer is trying to re-create the whole table and warning you about that.
It is possible to allow it to do so by disabling the option specified in the error message to "prevent saving changes that require the table to be recreated" but there is no need for this here.
You can just run
ALTER TABLE SAMPLE_UPL
ALTER COLUMN KORESKI VARCHAR(300) NULL
Or simply
ALTER TABLE SAMPLE_UPL
ALTER COLUMN KORESKI VARCHAR(300)
(as altering an existing column always sets it to allow NULL unless explicitly specified otherwise)
go in table design and checked check box this can allow you null values
script of this table
CREATE TABLE [dbo].[AWBuildVersion](
[SystemInformationID] [tinyint] IDENTITY(1,1) NOT NULL,
[Database Version] [nvarchar](25) NULL,
[VersionDate] [datetime] NOT NULL,
[ModifiedDate] [datetime] NOT NULL,
CONSTRAINT [PK_AWBuildVersion_SystemInformationID] PRIMARY KEY CLUSTERED
(
[SystemInformationID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
Table Definition:
CREATE TABLE [dbo].[tbl](
[Id1] [int] NOT NULL,
[Id2] [int] NOT NULL,
[Id3] [int] NOT NULL,
[IsActive] [bit] NOT NULL,
[CreatedTs] [datetime] NOT NULL,
CONSTRAINT [PK_tbl] PRIMARY KEY CLUSTERED
(
[Id1] ASC,
[Id2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
ALTER TABLE [dbo].[tbl] ADD CONSTRAINT [DF_tbl_IsActive] DEFAULT ((1)) FOR [IsActive]
GO
ALTER TABLE [dbo].[tbl] ADD CONSTRAINT [DF_tbl_CreatedTs] DEFAULT (getdate()) FOR [CreatedTs]
GO
In above table the I've composite primary key using "Id1" and "Id2" combination.
Now I want to include "Id3" in composite primary key, for that I am doing following:
ALTER TABLE tbl
DROP CONSTRAINT PK_tbl
ALTER TABLE [dbo].[tbl] ADD CONSTRAINT [PK_tbl] PRIMARY KEY CLUSTERED
(
[Id1] ASC,
[Id2] ASC,
[Id3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
GO
The above query runs perfectly fine on my local sql server db, but when I run it on Azure db I get error:
Tables without a clustered index are not supported in this version of
SQL Server. Please create a clustered index and try again.
How should I modify the composite primary key on azure sql?
Azure SQL Database's latest update (V12) allows you to have tables without clustered indexes (i.e. as heaps). If you upgrade your server to the latest version, you'll be able to run your queries to modify the PK successfully.
Other features enabled by V12: http://azure.microsoft.com/en-us/documentation/articles/sql-database-preview-whats-new/
How to upgrade: http://azure.microsoft.com/en-us/documentation/articles/sql-database-preview-upgrade/
The problem is that dropping the PK constraint also drops the underlying clustered index, and heaps are not permitted in Azure.
The best you can do is to create a new table with desired structure, copy the data over, drop the old table, rename the new one and recreate the FKs if any.
The operations you are doing is supported on old & V12 versions of SQL Database Servers. Clustered index is a requirement only for inserts to happen on non-V12 servers. You can create a heap fine in non-V12 database or drop & recreate the clustered index/constraint. So you should not get this error. How are you running these statements? And what tool are you using to run the statements?
my sql table:
CREATE TABLE [dbo].[PayrollParameter]
(
[PayrollParameterID] [CHAR](36) NOT NULL,
[Description] [NVARCHAR](50) NOT NULL,
[NumberOfDaysInMonth] [INT] NOT NULL,
[IsFixedDaysInMonth] [BIT] NOT NULL,
CONSTRAINT [PK_PayrollParameter] PRIMARY KEY CLUSTERED (
[PayrollParameterID] ASC )WITH (pad_index = OFF, statistics_norecompute =
OFF, ignore_dup_key = OFF, allow_row_locks = on, allow_page_locks = on) ON
[PRIMARY]
)
ON [PRIMARY]
GO
the database already contain records; I want to alter the table to set the default value of IsFixedDaysInMonth to Checked if NumberOfDaysInMonth!=0
How can i do this?
CREATE DEFAULT needs a constant value as the default
Is an expression that contains only constant values (it cannot include
the names of any columns or other database objects).
The only ways I know to do what you want would be to use a trigger or insert using a stored procedure.