How to cascade rename PK on table, MS SQL 2005 - sql-server

I have successfully been able to rename a table and drop all constraints on that table with foreign key relationships and build they all back up. However, now I am at a point where the PK_tblFoo exists in more than one place (when I transfer the table to another DB). Renaming the table does not rename the primary key.
How would I cascade rename the primary key? I have renamed the table, I just need to get this portion figured out.

I believe I will need to this manually, drop all FK constraints, run this guy:
IF EXISTS ( SELECT *
FROM sys.indexes
WHERE object_id = OBJECT_ID(N'[dbo].[tblFoo]')
AND name = N'PK_tblBusinessListings' )
ALTER TABLE [dbo].[tblFoo] DROP CONSTRAINT [PK_tblBusinessListings]
GO
ALTER TABLE [dbo].[tblFoo]
ADD CONSTRAINT [PK_tblFoo_1] PRIMARY KEY CLUSTERED ( [ListingID] ASC )
WITH ( PAD_INDEX = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF,
ONLINE = OFF ) ON [PRIMARY]
Then go through and set up all the FK constraint with the new PK name....errrgh....this is going to take a while.

You could also use a refactoring tool, I know Visual Studio Team Edition for Database Professionals could handle this.

Related

Why does a newly-inserted row show up in two filegroups on a partitioned table in SQL Server?

I partitioned an existing table by year. After inserting a new record for a date in 2020, the new record shows as part of the 2020 partition and in the primary filegroup. I'm having a hard time finding if that's what is supposed to happen, or if I have something configured incorrectly.
This is what the partitions look like after inserting the record. Before inserting the record, this query showed 3 records in the primary filegroup, and 3 records in the 2021 group.
I was expecting a new row in the 2020 partition and for the number of rows in the primary filegroup to remain at 3, but perhaps those are wrong expectations.
Does the primary filegroup always show the total of the partitions, or should rows only show up as being in just the partition in which they belong?
I can show how I set this all up, and I'd be happy to, but this question is more about what the results should look like. I don't want the same row in multiple partitions.
Edit
I just found this link. It shows the results of inserting data where new rows only show up in the correct partition and not also in primary. So it appears I've done something incorrectly.
https://www.sqlshack.com/how-to-automate-table-partitioning-in-sql-server/
Edit 2
The reason primary has all 4 rows may be that its upper boundary is null. Since primary already existed on the table, that was never modified. Perhaps I need to modify it?
Edit 3
Interesting that this link also shows the sum of the partitions within the primary.
https://www.mssqltips.com/sqlservertip/2888/how-to-partition-an-existing-sql-server-table/
Script that SSMS generated for partitioning
USE [Sandbox]
GO
BEGIN TRANSACTION
CREATE PARTITION FUNCTION [PunchPF1](datetimeoffset(7)) AS RANGE LEFT FOR VALUES (N'2020-01-01T00:00:00-05:00', N'2021-01-01T00:00:00-05:00', N'2022-01-01T00:00:00-05:00')
CREATE PARTITION SCHEME [PunchPS1] AS PARTITION [PunchPF1] TO ([Pre2020_Punch], [2020_Punch], [2021_Punch], [2022_Punch])
ALTER TABLE [time].[Punch] DROP CONSTRAINT [PK_Punch] WITH ( ONLINE = OFF )
ALTER TABLE [time].[Punch] ADD CONSTRAINT [PK_Punch] 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 [ClusteredIndex_on_PunchPS1_637515095430656187] ON [time].[Punch]
(
[PunchTime]
)WITH (SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF) ON [PunchPS1]([PunchTime])
DROP INDEX [ClusteredIndex_on_PunchPS1_637515095430656187] ON [time].[Punch]
COMMIT TRANSACTION
Edit 4
Here is the same query, but with IndexName and IndexID included.
Edit 5
Things look better now after doing this:
USE [Sandbox]
--------------------------------------------------------------------------------------------------------------------
-- Drop table, scheme, and function
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'Punch' AND TABLE_SCHEMA = 'time')
DROP TABLE time.Punch;
IF EXISTS (SELECT 1 FROM sys.partition_schemes WHERE name = 'PunchPS1')
DROP PARTITION SCHEME PunchPS1
IF EXISTS (SELECT 1 FROM sys.partition_functions WHERE name = 'PunchPF1')
DROP partition function PunchPF1
--------------------------------------------------------------------------------------------------------------------
-- Files and Filegroups
-- Add files and filegroups manually in SSMS because each SQL Server could have different file locations?
-- How to add a file and filegroup using SQL:
-- https://learn.microsoft.com/en-us/sql/t-sql/statements/alter-database-transact-sql-file-and-filegroup-options?view=sql-server-ver15
-- To see an example of creating filegroups in SQL, script the Sandbox DB AS CREATE...
--------------------------------------------------------------------------------------------------------------------
-- Partition Function
CREATE PARTITION FUNCTION [PunchPF1](datetimeoffset(7))
AS RANGE RIGHT FOR VALUES (N'2020-01-01T00:00:00-05:00', N'2021-01-01T00:00:00-05:00', N'2022-01-01T00:00:00-05:00')
--------------------------------------------------------------------------------------------------------------------
-- Partition Scheme
CREATE PARTITION SCHEME [PunchPS1]
AS PARTITION [PunchPF1] TO ([Pre2020_Punch], [2020_Punch], [2021_Punch], [2022_Punch])
--------------------------------------------------------------------------------------------------------------------
-- Table
CREATE TABLE [time].[Punch](
[Id] [bigint] IDENTITY(1,1) NOT NULL,
[EmployeeId] [bigint] NOT NULL,
[PunchTime] [datetimeoffset](7) NOT NULL
) ON [PunchPS1] (PunchTime)
--------------------------------------------------------------------------------------------------------------------
-- Add some data
INSERT INTO [time].[Punch] ([EmployeeId],[PunchTime]) VALUES (10,'2020-12-18 16:40:20')
INSERT INTO [time].[Punch] ([EmployeeId],[PunchTime]) VALUES (10,'2020-12-20 16:40:20')
INSERT INTO [time].[Punch] ([EmployeeId],[PunchTime]) VALUES (10,'2020-12-22 16:40:20')
INSERT INTO [time].[Punch] ([EmployeeId],[PunchTime]) VALUES (10,'2021-3-18 16:40:20')
As seen here, the boundaries look good, I'm using RANGE RIGHT, and the rows seem to show in the correct partition.
The only question I have now is if it's bad to have no clustered index?

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

How can Reference Foreign key to Multiple tables?

I am trying to create a BOM structure i have 6 product tables which contains different attributes and a BOMHEADER and BOMDETAIL tables. Before creating the BOM structure i like to Validate or check the existence of the bomitem in either of the six tables. So i tried to creating BOMHEADER field as shown below using multiple constraints, but i get the following error message
"The INSERT Statement conflicted with the FOREIGN KEY constraint
What is the best way to resolve the issue.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[BOMHEAD](
[bomItem] [int] NOT NULL,
[bomRev] [nvarchar](6) NOT NULL,
[rollup] [bit] NULL,
CONSTRAINT [PK_BOMHEAD_KEY_0] PRIMARY KEY CLUSTERED
(
[bomItem] ASC,
[bomRev] 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]
GO
ALTER TABLE [dbo].[BOMHEAD] WITH CHECK ADD FOREIGN KEY([bomItem])
REFERENCES [dbo].[parts] ([itemId])
GO
ALTER TABLE [dbo].[BOMHEAD] WITH CHECK ADD FOREIGN KEY([bomItem])
REFERENCES [dbo].[Tires] ([titemId])
GO
ALTER TABLE [dbo].[BOMHEAD] WITH CHECK ADD FOREIGN KEY([bomItem])
REFERENCES [dbo].[Discs] ([itemId])
GO
ALTER TABLE [dbo].[BOMHEAD] WITH CHECK ADD FOREIGN KEY([bomItem])
REFERENCES [dbo].[Rims] ([itemId])
GO
ALTER TABLE [dbo].[BOMHEAD] WITH CHECK ADD FOREIGN KEY([bomItem])
REFERENCES [dbo].[Wheel] ([wheelItemId])
GO
ALTER TABLE [dbo].[BOMHEAD] WITH CHECK ADD FOREIGN KEY([bomItem])
REFERENCES [dbo].[Assemblies] ([itemId])
GO
The structure you post is not check that bomItem is exists in any of that given table but it is required that bomItem must exists in ALL TABLES.
You should do it the other way round by making BOMHEAD to primary key table and set fk of other table to refer pk on BOMHEAD.
This way it will guarantee that every other part table will have BOMHEAD.
The way you did is to guarantee that BOMHEAD will have every other parts.
But if you insist that bomItem need to check for existence in either of the six tables(maybe to prevent unwanted reference from other table?),You can't use fk what you need is check constrain with user defined function or create association table which maintain the relation between BOMHEAD and others.
You should have general table with BOMs that are referenced via Foreign Key by all these tables.

Drop and add constraints in one stored procedure

I would like to drop a primary key and then add a primary key to the same column in 1 stored procedure.
I have the drop constraints within Begin Transaction' andCommit Transactionthen try to add the constraints within another set ofBegin TransactionandCommit Transaction`.
I am getting the error that a primary key already exists for this column when it was dropped in the first set of transactions.
This is the code:
BEGIN TRANSACTION
ALTER TABLE [dbo].[Lens] DROP CONSTRAINT [FK_Lens_Style];
ALTER TABLE [dbo].[Lens] DROP CONSTRAINT [FK_Lens_Type];
ALTER TABLE [dbo].[Coating] DROP CONSTRAINT [PK_Coatings];
ALTER TABLE [dbo].[CoatingCost] DROP CONSTRAINT [PK_CoatingCost];
COMMIT TRANSACTION
BEGIN TRANSACTION
ALTER TABLE [dbo].[Coating]
ADD CONSTRAINT [PK_dbo.Coating]
PRIMARY KEY CLUSTERED ([CoatingId] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
COMMIT TRANSACTION
If the first set of constraints are dropped and committed, shouldn't I be able to add a primary key on the column that previously had a primary key?
UPDATE
I think I know the problem. It is because there is a Foreign Key associated with the primary key that I am trying to drop.
I will need to drop all of the foreign keys associated with all of the primary keys that I am trying to drop. Then add the primary keys back. Then add the foreign keys back.
Are you sure that the problem is not with the same index name existing in the database in the moment when your code tries to create one? The name of an index must be unique in the entire database scope not only in a single table scope.
You might want to diagnose it by putting a below query before, between and after your transaction operations:
SELECT
so.name AS tableName
, si.name AS indexName
, si.type_desc AS indexType
, si.is_primary_key AS isPK
FROM
sys.indexes AS si
JOIN sys.objects AS so ON si.object_id = so.object_id
WHERE
si.name IS NOT NULL /*otherwise it will select all tables without explicit index*/
AND
so.type = 'U'/*otherwise it unnecessarily will select indexes of system tables*/

Include not available in covering indexes in SQL Server 2008 Express

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.

Resources