Generating Database Scripts in SQL Server Express - sql-server

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.

Related

Fix SQL Server identity and restore the proper numeration order

I have SQL Server 2014 restarted unexpectedly and that broke straight auto-increment identity sequences on entities. All new entities inserted to tables have their identities incremented by 10 000.
Let's say, if there were entities with IDs "1, 2, 3" now all newly inserted entities are like "10004, 10005".
Here is real data:
..., 12379, 12380, 12381, (after the restart) 22350, 22351, 22352, 22353, 22354, 22355
(Extra question here is why has it inserted the very first entity after the restart with 22350? I thought it should have been 22382 as it's the latest ID by that moment 12381 + 10001 = 22382)
I searched and found out the reasons for what happened. Now I want to prevent such situations in the future and fix the current jump. It's a production server and users continuously add new stuff to the DB.
QUESTION 1
What options do I have here?
My thoughts on how to prevent it are:
Use sequences instead of identity columns
Disable T272 flag, reseed identity causing it started from the latest right value (I guess there is such an option)
What are the drawbacks of the two above? Please advise some new ways if there are.
QUESTION 2
I'm not an expert in SQL Server. And now I need to normalize and adjust the numeration of entities since it's a business requirement. I think I need to write a script that updates wrong ID values setting them to be right. Is it dangerous to update identity values? Some tables have dependent records. What does this script may look like?
OTHER INFO
Here is how my identity columns declared (got this using "Generate scripts" option in SSMS):
CREATE TABLE [dbo].[Tasks]
(
[Id] [uniqueidentifier] NOT NULL,
[Created] [datetime] NOT NULL,
...
[TaskNo] [bigint] IDENTITY(1,1) NOT NULL
CONSTRAINT [PK_dbo.Tasks]
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]
I also use Entity Framework 6 for database manipulating.
I will be happy to provide any other information by request if needed.
I did this once in a weekend of downtime and ended up having to reseed the whole table, by turning off the identity insert and then updating each row with a row numbers. This was based on the tables correct sort order to make sure the sequence was correct.
As it updated the whole table, (500 million rows) it generated a hell of a lot of transaction log data. Make sure you have enough space for this and presize the log if required.
As said above though, if you must rely on the identity column then amend it to a sequence. Also, make sure your rollback mechanism is good if there is an error during insert and the sequence has all ready been incremented.

Why does this insert statement not match the table?

I am using a Visual Studio 2015 Database Project to attempt to insert rows into database tables which have been created by the project. The Insert sql works in the same table in SSMS, but not when run via the project.
I get the error: Column name or number of supplied values does not match the table definition.
TSQL insert script:
if not exists (select top 1 1 from [dbo].[PricingGroupTypes]) begin
INSERT INTO [dbo].[PricingGroupTypes]
([Name])
VALUES
('User')
,('Product Format')
print 'Pricing Group Types added'
end
Table Definition (in DB project):
CREATE TABLE [dbo].[PricingGroupTypes] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (250) NOT NULL,
CONSTRAINT [PK_PricingGroupTypes] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Table Definition (via ssms):
USE [Toyland]
GO
/****** Object: Table [dbo].[PricingGroupTypes] Script Date: 11/14/2016 11:05:05 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[PricingGroupTypes](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](250) NOT NULL,
CONSTRAINT [PK_PricingGroupTypes] 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
Other inserts in the same script do not seem to fail, but the overall script will roll back so the database is empty after execution. And, like I said, the exact same script WORKS when I run it in SQL Server Management Studio.
Perhaps there's some Visual Studio setting I'm missing, but this is about the most straightforward bit of script in the entire project, so you can see why I'm perplexed.
In the end, there was a comment here suggesting it was perhaps a problem with some other part of my overall script generated by the project. This turned out to be the case. I have now resolved the issue and the code in the original question is unchanged.
Unfortunately I don't know, anymore, which other part of the big script was the culprit, since I had to go through and make a few other changes to get everything running smoothly, but there did not appear to be any problems with the SQL in my original question.
if not exists (select top 1 1 from [dbo].[PricingGroupTypes]) begin
INSERT INTO [dbo].[PricingGroupTypes]
([Name])
VALUES
('User')
,('Product Format')
print 'Pricing Group Types added'
end
Your problem is that you're trying to insert two values into one column. Trying to insert 'User' and 'Product Format' into [Name] will kick back an error because it needs a destination for product format. Update your insert statement to include the second column and it should go.

I am using ssis and I am getting this error "Violation of PRIMARY KEY constraint .Cannot insert duplicate key in object . The duplicate key value is

I am new to SSIS and I am getting an error message . Can anyone help me ? There are not duplicates in my data
The error message is
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 11.0" Hresult: 0x80040E2F Description: "Violation of PRIMARY KEY constraint 'PK_DimCourse'. Cannot insert duplicate key in object 'dbo.DimCourse'. The duplicate key value is (CS1301).".
My current table looks like this
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[DimCourse](
[CourseCode] [nvarchar](10) NOT NULL,
[SubjectCode] [nvarchar](10) NOT NULL,
[CourseNumber] [nvarchar](10) NOT NULL,
[CourseTitle] [nvarchar](50) NOT NULL,
[Level1] [nvarchar](20) NOT NULL,
[Level2] [nvarchar](20) NOT NULL,
CONSTRAINT [PK_DimCourse] PRIMARY KEY CLUSTERED
(
[CourseCode] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I know I am too late to answer. I was getting the similar error message, found out what was the problem, and solved it. I hope it will help the future readers.
Scenario:
I have a source table with dbo.Codes with primary key
combination(CodeID, CodeName).
In order to create my destination
table, I have used the SQL Server-->Database-->Tasks-->Generate
Scripts, option.
Then, in the SSIS package, I simply used the OLE DB
Source and OLE DB Destination element. It was returning
error: "Violation of PRIMARY KEY constraint 'pkCodes'. Cannot insert
duplicate key in object 'dbo.Codes'. The duplicate key value is
(106, da7A).".
What I have tried to solve:
I have tried to use the sql command as source: Select CodeID, CodeName from dbo.Codes GROUP BY CodeID, CodeName. It was still returning error. I got confused at this point.
After searching online, I found a tips to add a SSIS Toolbox-->Common-->Sort element between OLE DB Source and OLE DB Destination. I checked the option "Remove rows with duplicate sort values" in the Sort element. I was still getting error.
Then, I had enabled the data viewer between OLE DB Source and Sort element. I could see there are two rows: 106, da7a and 106, da7A in the source table.
What is the real problem?
My source table coulmn CodeName is case sensitive but my CodeName column in the destination table is not case sensitive. This has occured because, sql server generate script option, Script Collation is set to false by default.
Solution that worked for me:
I recreated my destination table with Script Collation option: True, which made my destination column case sensitive and it has solved my problem.
A record with CourseCode = 'CS1301' already exists in the target and the same CourseCode will be inserted by SSIS from the source which leads to a duplicate.
Either that or your target does not contain CourseCode = 'CS1301' yet, but your source data contains two rows both with the same CourseCode. By inserting the duplicate into the target environment will also lead to a duplicate.
I would suggest querying your source data for CourseCode = 'CS1301' to see if you find two rows. If there is only one row, query your target data for CourseCode = 'CS1301'. If there is also one row, compare and depending on the situation you probably have to delete one of them.
While on the production server a "perfectly good" package can fail days, weeks, or months later with a false duplicate primary key error. In my experience this happens when a package has the development standard which is something like EncryptWithUserKey. This can be avoided by following MS Standard practice by encrypting the package, (or perhaps setting as do not save sensitive date which I didn't bother trying). It is also good practice to parameterize connections (configure connection manager dynamically).

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.

Sql Server 2005 Primary Key violation on an Identity column

I’m running into an odd problem, and I need some help trying to figure it out.
I have a database which has an ID column (defined as int not null, Identity, starts at 1, increments by 1) in addition to all the application data columns. The primary key for the table is the ID column, no other components.
There is no set of data I can use as a "natural primary key" since the application has to allow for multiple submissions of the same data.
I have a stored procedure, which is the only way to add new records into the table (other than logging into the server directly as the db owner)
While QA was testing the application this morning, they to enter a new record into the database (using the application as it was intended, and as they have been doing for the last two weeks) and encountered a primary key violation on this table.
This is the same way I've been doing Primary Keys for about 10 years now, and have never run across this.
Any ideas on how to fix this? Or is this one of those cosmic ray glitches that shows up once in a long while.
Thanks for any advice you can give.
Nigel
Edited at 1:15PM EDT June 12th, to give more information
A simplified version of the schema...
CREATE TABLE [dbo].[tbl_Queries](
[QueryID] [int] IDENTITY(1,1) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL,
[Address] [varchar](150) NOT NULL,
[Apt#] [varchar](10) NOT NULL
... <12 other columns deleted for brevity>
[VersionCode] [timestamp] NOT NULL,
CONSTRAINT [PK_tbl_Queries] PRIMARY KEY CLUSTERED
(
[QueryID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
(also removed the default value statements)
The stored procedure is as follows
insert into dbo.tbl_Queries
( FirstName,
LastName,
[Address],
[Apt#]...) values
( #firstName,
#lastName,
#address,
isnull(#apt, ''), ... )
It doesn't even look at the identity column, doesn't use IDENTITY, ##scope_identity or anything similar, it's just a file and forget.
I am as confident as I can be that the identity value wasn't reset, and that no-one else is using direct database access to enter values. The only time in this project that identity insert is used is in the initial database deployment to setup specific values in lookup tables.
The QA team tried again right after getting the error, and was able to submit a query successfully, and they have been trying since then to reproduce it, and haven't succeeded so far.
I really do appreciate the ideas folks.
Sounds like the identity seed got corrupted or reset somehow. Easiest solution will be to reset the seed to the current max value of the identity column:
DECLARE #nextid INT;
SET #nextid = (SELECT MAX([columnname]) FROM [tablename]);
DBCC CHECKIDENT ([tablename], RESEED, #nextid);
While I don't have an explanation as to a potential cause, it is certinaly possible to change the seed value of an identity column. If the seed were lowered to where the next value would already exist in the table, then that could certainly cause what you're seeing. Try running DBCC CHECKIDENT (table_name) and see what it gives you.
For more information, check out this page
Random thought based on experience
Have you synched data with, say, Red Gate Data Compare. This has an option to reseed identity columns. It's caused issues for use. And another project last month.
You may also have explicitly loaded/synched IDs too.
Maybe someone insert some records logging into the server directly using a new ID explicity, then when the identity auto increment field reach this number a primary key violation happened.
But The cosmic ray is algo a good explanation ;)
Just to make very, very sure...you aren't using an IDENTITY_INSERT in your stored procedure are you? Some logic like this:
declare #id int;
Set #id=Select Max(IDColumn) From Sometable;
SET IDENTITY_INSERT dbo.SomeTable ON
Insert (IDColumn, ...others...) Values (#id+1, ...others...);
SET IDENTITY_INSERT dbo.SomeTable OFF
.
.
.
I feel sticky just typing it. But every once in awhile you run across folks that just never quite understood what an Identity column is all about and I want to make sure that this is ruled out. By the way: if this is the answer, I won't hold it against you if just delete the question and never admit that this was your problem!
Can you tell that I hire interns every summer?
Are you using functions like ##identity or scope_identity() in any of your procedures? if your table has triggers or multiple inserts you could be getting back the wrong identity value for the table you want
Hopefully that is not the case, but there is a known bug in SQL 2005 with SCOPE_IDENTITY():
http://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811
The Primary Key violation is not necessarily coming from that table.
Does the application touch any other tables or call any other stored procedures for that function? Are there any triggers on the table? Or does the stored procedure itself use any other tables or stored procedures?
In particular, an Auditing table or trigger could cause this.

Resources