Include not available in covering indexes in SQL Server 2008 Express - sql-server

In MS SQL Server Manager Studio for 2008 Express, the "Included Columns" field is always grayed out in the "Indexes/Keys" window in the Database Diagram designer.
Per the help, this should be available so long as I'm not creating a clustered index.
Further, if I run a query to create the index (which runs fine), the created query doesn't list for the table it was added against.
I don't see anywhere where MS says this feature is unavailable in the Express version.
Any ideas?
Further data:
This is the script that creates the table:
CREATE UNIQUE INDEX IX_SocialTypes_Cover ON ClientSocialTypes(ClientID, SocialTypeID, [Source]) INCLUDE (URLID)
Here is the table gen script (the index is missing):
CREATE TABLE [dbo].[ClientSocialTypes](
[SocialTypeID] [int] IDENTITY(1,1) NOT NULL,
[ClientID] [int] NOT NULL,
[SocialTypeClassID] [tinyint] NOT NULL,
[Source] [nvarchar](50) NOT NULL,
[TagCount] [int] NOT NULL,
[URLID] [int] NULL,
CONSTRAINT [PK_ClientSources] PRIMARY KEY CLUSTERED
(
[SocialTypeID] 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
ALTER TABLE [dbo].[ClientSocialTypes] WITH CHECK ADD CONSTRAINT [FK_ClientSocialTypes_Clients] FOREIGN KEY([ClientID])
REFERENCES [dbo].[Clients] ([ClientID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[ClientSocialTypes] CHECK CONSTRAINT [FK_ClientSocialTypes_Clients]
GO
ALTER TABLE [dbo].[ClientSocialTypes] WITH CHECK ADD CONSTRAINT [FK_ClientSocialTypes_SocialTypeClasses] FOREIGN KEY([SocialTypeClassID])
REFERENCES [dbo].[SocialTypeClasses] ([SocialTypeClassID])
GO
ALTER TABLE [dbo].[ClientSocialTypes] CHECK CONSTRAINT [FK_ClientSocialTypes_SocialTypeClasses]
GO
ALTER TABLE [dbo].[ClientSocialTypes] ADD CONSTRAINT [DF_ClientSocialTypes_SocialTypeClassID] DEFAULT ((1)) FOR [SocialTypeClassID]
GO
ALTER TABLE [dbo].[ClientSocialTypes] ADD CONSTRAINT [DF_ClientSocialTypes_TagCount] DEFAULT ((0)) FOR [TagCount]
GO
ALTER TABLE [dbo].[ClientSocialTypes] ADD CONSTRAINT [DF_ClientSocialTypes_HasTrackedURL] DEFAULT ((0)) FOR [URLID]
GO

There's TWO different index dialogs. An ancient horrible awful one, and a new (only just discovered it) one that actually lets you change these things.
OLD HORRIBLE ONE
Right click on a table in your main tables list
Click 'Design'
Right click on the list of columns and select 'Indexes/Keys'
This doesn't let you change included columns.
NEW NICE ONE
Expand the table in your main tables list to show the 'Columns', 'Keys', 'Constraints', 'Triggers' etc folders
Expand the Indexes folder
Right click Indexes folder for New Index
Right click existing index and click Properties to edit an existing index
This newer dialog allows you to do a lot more and I'm kind of disappointed in Microsoft for keeping the old one alive and for how long it's taken me to discover it.

It turns out this is grayed out in the full version of SQL Server too. In SSMS, use the Object Explorer (not the Designer) to navigate to {database_name} > Tables > {table_name} > Indexes to manage indexes that have includes.

The index may actually be a unique constraint (using CREATE/ALTER TABLE) rather than an index created using CREATE INDEX. Unique constraints don't allow INCLUDEs.
It's quite confusing... generate a script for the index/key entry or table and you'll be able to confirm.
Edit:
When you create the index separately you have to refresh Object Explorer
Do you have 2 SocialType tables in different schemas? (eg dbo.SocialType and [domain\myuser].SocialType). This can happen if you don't specify the schema in DDL statements.

Related

MS PowerApps: How to "Patch" a SQL Table with Composite Primary Key

I am relatively new to MS PowerApps
I have a SQL Server Express installed on a onsite server with a Gateway for PowerApps
My SQL Server table has a composite primary key, it is defined as:
CREATE TABLE [GFX_Information].[BusinessParnterAccess]
(
[BpAccesID] [int] IDENTITY(1,1) NOT NULL,
[CreatedDate] [datetime] NOT NULL,
[UpdatedDate] [datetime] NOT NULL,
[LastOperatorID] [int] NOT NULL,
[CreateByID] [int] NOT NULL,
[BPID] [int] NOT NULL,
[AllowedOperatorID] [int] NOT NULL,
[AccessFlag] [varchar](10) NULL,
PRIMARY KEY CLUSTERED ([AllowedOperatorID] ASC, [BPID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [GFX_Information].[BusinessParnterAccess]
ADD DEFAULT (GETDATE()) FOR [CreatedDate]
GO
ALTER TABLE [GFX_Information].[BusinessParnterAccess]
ADD DEFAULT (GETDATE()) FOR [UpdatedDate]
GO
I am trying to work out how to "Patch" a new record.
Currently, using the OnVisible event I create a variable to hold the last BpAccesID like this
UpdateContext ({varLastAccessID:First(SortByColumns('[GFX_Information].[BusinessParnterAccess]',"BpAccesID",Descending)).BpAccesID});
I am using a manual set of values for the Patch Command for testing purposes. The Patch command is
Patch('[GFX_Information].[BusinessParnterAccess]',Defaults('[GFX_Information].[BusinessParnterAccess]')
,{BpAccesID:varLastAccessID+1
,CreatedDate: Now()
,UpdatedDate:Now()
,LastOperatorID:4
,CreateByID:4
,BPID:342
,AllowedOperatorID:4
,AccessFlag:"RW" });
However, this does not throw an error I can detect nor can I see what I am missing
Can any one provide any ideas please?
I was reading this, and this is a suggestion is based on my knowledge of SQL Server and a quick read about Patch. It may help you, or may not (I'm sorry). And also just confirming: I'm guessing that the question is "this doesn't create a new row and I cannot see why?"
I would guess that your issue is with BPAccessId. You've set it as an identity: [BpAccesID] [int] IDENTITY(1,1) NOT NULL,
However, you explicitly insert a value into it
Patch('[GFX_Information].[BusinessParnterAccess]',Defaults('[GFX_Information].[BusinessParnterAccess]')
,{BpAccesID:varLastAccessID+1
Of course, you usually cannot insert into an IDENTITY column in SQL Server - you need to set IDENTIY_INSERT on (then off again after you finish). Also, as an aside, one of the reasons for IDENTITY PK columns is to always create a new row with a valid PK. How does the approach above work for concurrency e.g., two users trying to create a new row at the same time?
Anyway, some potential solutions off the top of my head. Once again, this is based off my knowledge of SQL Server only.
Alter the MS Powerapps statement to work with the IDENTITY (I'll leave this up to you) - whether the equivalent of SET IDENTITY_INSERT table ON; or otherwise
Remove the IDENTITY property from BPAccessID (e.g., leave it as a pure int)
Make the Primary Key a composite of all three columns e.g., AllowedOperatorID, BPID, BPAccessID
Make BPAccessID the Primary Key but non-clustered, and make a unique clustered index for AllowedOperatorID, BPID
For the bottom two, as BPAccessID is still an IDENTITY, you'll need to let SQL Server handle calculating the new value.
If you are not using foreign keys to this table, then the bottom two will have similar effects.
However, if there are foreign keys, then the bottom one (a non-clustered PK and clustered unique index on the other two) is probably the closest to your current setup (and is actually what I would typically do in a table structure like yours, regardless of PowerApps or other processing).

Why is SSMS-produced script missing indexes?

SSMS 17.4, SQL Server 2017 Developer's Edition on Win10 1709
I have installed the WorldWideImporters sample database. One of the tables, Sales.Customers, has several foreign keys AND several foreign key indexes. When scripting the table (Script Table, CREATE To…), the script includes the foreign keys, but not the foreign key indexes. If I just change the name of the table and run the generated script, the table is created with all of the FK constraints, but none of the FK indexes.
For something you can see even if you don't have the WWI sample installed, I did this.
CREATE TABLE bar (
bar_id int,
col1 varchar(20),
CONSTRAINT pk_bar PRIMARY KEY CLUSTERED (bar_id)
)
CREATE TABLE foo (
foo_id int,
foobar_id int,
col1 varchar(20),
CONSTRAINT pk_foo PRIMARY KEY CLUSTERED (foo_id)
)
ALTER TABLE foo WITH CHECK
ADD CONSTRAINT FK_bar FOREIGN KEY (foobar_id) REFERENCES bar (bar_id)
ALTER TABLE foo CHECK CONSTRAINT FK_bar
That creates two tables, with foo having a FK constraint to bar. I then scripted the table from SSMS.
CREATE TABLE [dbo].[foo](
[foo_id] [int] NOT NULL,
[foobar_id] [int] NULL,
[col1] [varchar](20) NULL,
CONSTRAINT [pk_foo] PRIMARY KEY CLUSTERED
(
[foo_id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [USERDATA]
) ON [USERDATA]
GO
ALTER TABLE [dbo].[foo] WITH CHECK ADD CONSTRAINT [FK_bar] FOREIGN KEY([foobar_id])
REFERENCES [dbo].[bar] ([bar_id])
GO
ALTER TABLE [dbo].[foo] CHECK CONSTRAINT [FK_bar]
GO
So far, so good.
But then I added an index on foo on the FK column.
CREATE NONCLUSTERED INDEX FK_bar ON foo (foobar_id)
Scripting the table then produces the exact same script as above. Thus, SSMS is producing the same script whether there's an index on the FK column or not. (I confirmed with sp_helpindex that the FK index does indeed exist.)
Is this a bug in SSMS or am I mis-understanding something?
Scripting out the index is turned off by default in SSMS. Personally, that is one of the first things I turn back on along with scripting permissions and triggers. You can find this setting by:
In SSMS, open the Tools menu and pick Options
Scroll down to SQL Server Object Explorer and expand the tree
Click on the Scripting node and change Script indexes to true

SQL Server Management Studio does NOT let me create multiple foreign keys to multiple primary keys

I have a table ApplicationRegion in a one-to-many relationship to Translation.
I want to set FK's from Translation.appname/isocode to ApplicationRegion.appname/isocode
But that did not work as you can see from the screenshot.
When the FK configure window opens 3 columns are shown on the left/right side
appname
isocode
resourcekey
Then I chose as parent table ApplicationRegion and removed the resource key column from the FK setting.
And clicked OK but then I got the error you see on the screenshot.
Finally I made it work with that workaround and I would like to know why I had to use this workaround?
Remove PK from Translation.ResourceKey column
Open FK configure window
Only 2 columns appear now as foreign keys
I click OK
Now I add the PK again to Translation.ResouceKey column
I added test data to all 3 tables and everything is fine.
WHY this workaround?
UPDATE
HAHA...
I think you must have hit a weird glitch in SSMS. I was able to create your schema using SSMS 2014 without any errors. It did pre-fill the three composite primary key columns when adding the new FK. I was careful to make sure they were all blanked out before I started to add the two columns in the FK. Maybe SSMS thought one of the blank rows still had data in it.
Edit: Just had one more thought, SSMS is know for caching any changes that are made when editing a table. For example, if you go to modify two tables and have both edit windows open. Then you change the PK in one window and then try to reference it in the second window, it will error because it has cached what the schema was for the first table when the window was first opened.
Here is my generated DDL:
CREATE TABLE [dbo].[AppRegion](
[appname] [nvarchar](50) NOT NULL,
[isocode] [char](5) NOT NULL,
CONSTRAINT [PK_AppRegion] PRIMARY KEY CLUSTERED
(
[appname] ASC,
[isocode] ASC
)
) ON [PRIMARY]
CREATE TABLE [dbo].[Translation](
[ResourceKey] [nvarchar](128) NOT NULL,
[appname] [nvarchar](50) NOT NULL,
[isocode] [char](5) NOT NULL,
[text] [nvarchar](400) NULL,
CONSTRAINT [PK_Translation] PRIMARY KEY CLUSTERED
(
[ResourceKey] ASC,
[appname] ASC,
[isocode] ASC
)
) ON [PRIMARY]
ALTER TABLE [dbo].[Translation] ADD CONSTRAINT [FK_Translation_AppRegion] FOREIGN KEY([appname], [isocode])
REFERENCES [dbo].[AppRegion] ([appname], [isocode])

Convert INT to BIGINT in SQL Server

SQL 2005, 600,000,000 rows.
I have a table called Location currently using the data type INT in identity PK column LocationID. I would like to attempt converting this data type to BIGINT.
The following script I think should help to allow inserted into the PK column but i am unsure how to progress form here.
SET IDENTITY_INSERT LOCATION ON /*allows insert into the identity column*/`
SET IDENTITY_INSERT LOCATION OFF /*Returns the identity column to initial state*/`
Location table create script below:
CREATE TABLE [dbo].[Location](
[LocationID] [int] IDENTITY(1,1) NOT NULL,
[JourneyID] [int] NULL,
[DeviceID] [int] NOT NULL,
[PacketTypeID] [int] NULL,
[PacketStatusID] [int] NULL,
CONSTRAINT [Location_PK] PRIMARY KEY CLUSTERED
(
[LocationID] 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
ALTER TABLE [dbo].[Location] WITH CHECK ADD CONSTRAINT [Device_Location_FK1] FOREIGN KEY([DeviceID])
REFERENCES [dbo].[Device] ([DeviceID])
GO
ALTER TABLE [dbo].[Location] CHECK CONSTRAINT [Device_Location_FK1]
GO
ALTER TABLE [dbo].[Location] WITH CHECK ADD CONSTRAINT [PacketStatus_Location_FK1] FOREIGN KEY([PacketStatusID])
REFERENCES [dbo].[PacketStatus] ([PacketStatusID])
GO
ALTER TABLE [dbo].[Location] CHECK CONSTRAINT [PacketStatus_Location_FK1]
GO
ALTER TABLE [dbo].[Location] WITH CHECK ADD CONSTRAINT [PacketType_Location_FK1] FOREIGN KEY([PacketTypeID])
REFERENCES [dbo].[PacketType] ([PacketTypeID])
GO
ALTER TABLE [dbo].[Location] CHECK CONSTRAINT [PacketType_Location_FK1]
One option i think would be to copy the data to a new table then delete the old table and rename the new one however we have constraints that will need to be dropped for this to work.
Your idea of a new table is the way to go.
On a development server, you can see the script that SSMS would produce if you change the data type using the table designer. It is a good start. This will add triggers and constraints back afterwards.
A tool like Red gate SQL Compare also allows you to check that everything was created OK

Generating Database Scripts in SQL Server Express

I generate change scripts for my database to keep it under source control, and a strange thing happens every time:
I have a FlowFolder table, and clicking Generate Scripts creates the following two scripts:
dbo.FlowFolder.Table.sql:
USE [NC]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[FlowFolder](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ParentId] [dbo].[ParentId] NULL,
[ParentType] [dbo].[CLRTypeName] NOT NULL,
[Name] [dbo].[EntityName] NOT NULL,
[Description] [dbo].[EntityDescription] NULL,
[LastChanged] [int] NULL,
CONSTRAINT [PK_FlowFolder] 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]
GO
SET ANSI_PADDING OFF
GO
DF\_FlowFolder_LastChanged.Default.sql:
USE [NC]
GO
ALTER TABLE [dbo].[FlowFolder] ADD CONSTRAINT [DF_FlowFolder_LastChanged]
DEFAULT ((0)) FOR [LastChanged]
GO
Question
Why does SQL Server Express produce two files?
Why doesn't it place this constraint as a DEFAULT(0) attribute on the LastChanged field in the CREATE TABLE statement?
How can I force SQL Server to generate a consolidated script for each change instead of splitting them up?
EDIT:
How we generate scripts. At first, it was a single file. But, unfortunately, SQLEXPRESS does not keep the order of the database entities from save to save. Meaning, that even a small change in the schema could result in a script widely different from the predecessor. This is very inconvenient if one wishes to compare the differences in schemas. Hence we adopted another approach. We generate script per database entity (not data, but schema entity, like table, user type, etc ...) and then apply a small utility that removes the comment inserted by SQLEXPRESS in each file stating the date of generation. After that it is clearly visible which schema entities have changed from revision to revision.
In conclusion, we must generate script per schema entity.
About the DEFAULT(0) constraints - we really do not need them to be named constraints, so placing them on the column definition is fine.
Do you have "File per object" selected on the output option panel of the wizard?
Because you can't give constraints names when they're embedded in CREATE TABLE
Make sure "Single file" is selected on the output option panel -- or try "Script to New Query Window"
Unfortunately, the feature you're looking for doesn't exist.
All constraints are given names -- even unnamed constraints are given names. SQL Server doesn't keep track of which names it created and which ones you created, so in the script generation process, it has to split them off.
Usually, it's better to manage this process in reverse. In other words, have a collection of script files that you combine together to create the DB. That way, you can have the script files structured however you want. Team System Data Edition does this all automatically for you. A regular DB project lets you keep them separate, but it's more work on the deployment side.

Resources