After no row deletion, but after getting the 60 existing rows by local subscription to replication from another SQL Server instance, I'm inserting new rows with:
INSERT INTO [Business].[dbo].[ImagesTable] (Filename, Title, Price, PriceString, Category, CategoryRank)
VALUES ('vegan1.jpg', 'vegan1', 380000, '380,000', 'delices vegan', 0)
But this will fail since the ID will start over somewhere (9 in this case), instead of starting at the last ID used +1, ie., 61 in my case.
System.Data.SqlClient.SqlException: 'Violation of PRIMARY KEY constraint 'PK_ImagesTable'. Cannot insert duplicate key in object 'dbo.ImagesTable'. The duplicate key value is (9).
My table is set to have autoincrement, therefore I should not have to use explicit IDENT_CURRENT('ImagesTable'). Why is this happening ?
Furthermore and despite this, when I try to insert explicitly ID I have:
Cannot insert explicit value for identity column in table 'ImagesTable' when IDENTITY_INSERT is set to OFF.
What is the recommended way to add new rows? How can I insert new rows with the ID being automatically set?
If the presence of DB replication is not propagating the Identity seed, how should I deal with this so I don't have to manage duplicate key errors (I'm certain that I'm not inserting duplicates)?
You need to segment your IDENTITY column ranges in bidirectional replication.
https://learn.microsoft.com/en-us/sql/relational-databases/replication/publish/replicate-identity-columns?view=sql-server-ver15
Related
I have a table Line_Production_Plan in SQL Server; it has a UID column (int, auto-increment, identity).
It also has multiple other columns. One of them is execution_priority (int, not null).
When I insert a new row into the table (via a stored procedure (without passing execution_priority or UID as parameters)), I want execution_priority to take up the same value as the corresponding UID column in during insert. Is there a way to set the default value of a column, equal to another upon insert?
The execution, priority needs to be changed from time to time. Hence I can't use identity or auto increment.
You should use IDENT_CURRENT to get the last identity value generated for the table Line_Production_Plan.
Try this code:
INSERT INTO Line_Production_Plan (execution_priority)
VALUES ((SELECT IDENT_CURRENT('Line_Production_Plan')));
The primary key of my table is an Identity column of an ID. I want to be able to insert a new row and have it know what the last ID in the table currently is and add one to it. I know I can use Scope Identity to get the last inserted column from my code, but I am worried about people manually adding entries in the database, because they do this quite often. Is there a way I can look at the last ID in the table and not just the last ID my code inserted?
With a SQL Identity column, you don't need to do anything special. This is the default behavior. SQL Server will handle making sure you don't have collisions regardless of where the inserts come from.
The ##Identity will pull the latest identity, and scope_identity will grab the identity from the current scope.
A scope is a module: a stored procedure, trigger, function, or batch. Therefore, if two statements are in the same stored procedure, function, or batch, they are in the same scope.
If you don't want to allow manual entries to the primary column, then you can add Identity constraint to it along with primary key constraint.
Example, while creating a table,
CREATE Table t_Temp(RowID Int Primary Key Identity(1,1), Name Varchar(50))
INSERT Into t_Temp values ('UserName')
INSERT Into t_Temp values ('UserName1')
SELECT * from t_Temp
You can query the table and get the next available code in one SQL query:
SELECT COALESCE(MAX(CAST("RowID" AS INT)),0) +1 as 'NextRowID' from <tableName>
The "0" here is a default, meaning if there are no rows found, the first code returned would be (0+1) =1
Generally I have 999 instead of the 0 as I like my RowID/primary key etc. to start at 1000.
I have a database generated by Entity Framework code-first. I have a table with 11000 rows and 5 columns.
The column Id is the primary key:
On insert from an application (using EF), I got an error the first time; after some research I went to database in order to manually insert a record to see if it is working, and I get this error:
All columns are foreign keys and the value 1 exists for each.
Can someone tell me why I get this error?
Like I said, the table has already 11000 rows, not error on select query, no error on update, during insert the primary key generated by database is not correct!
The key 10987 exists!
Your id is off for some reason. So when you add a new record it's trying to reuse an existing one. Use "DBCC CHECKIDENT('CandidatePositionStatus', RESEED, 11000);" so the next id value it tries to insert should be 11001, a new value.
I am using SQL Server Management Studio and I want to change an auto increment primary key value of a table row, with a different value. SQL Server Management Studio after opening the table for edit, shows this field grayed for all rows, of course.
Is it possible? I want to use the number of a row we deleted by mistake, therefore it's valid (there is no conflict with other primary key values) and - most important of all - the next row added in the DB should have an intact auto incremented value.
Thanks.
EDIT: losing the link with other table records on this PK is not an issue for this row. We can restore it manually.
Not necessarily recommended but, insert a copy of the row where you want to change the number, but with the ID you require:
SET IDENTITY_INSERT aTable ON
GO
-- Attempt to insert an explicit ID value of 3
INSERT INTO aTable (id, product) VALUES(3, 'blah')
GO
SET IDENTITY_INSERT aTable OFF
GO
Then delete the row with the number you don't want (after you update any FK references).
More details here: http://technet.microsoft.com/en-us/library/aa259221(v=sql.80).aspx
For posterity, to clarify the question in the comment below, the auto increment value will only be affected if you insert a value greater than the current maximum.
Quoting from linked article:
If the value inserted is larger than the current identity value for
the table, SQL Server automatically uses the new inserted value as the
current identity value.
This question already has answers here:
How to insert into a table with just one IDENTITY column?
(5 answers)
Closed 1 year ago.
I have a table Administrator with only one column, adminId which is the primary-key. Because of business rules it has to be this way.
I'd like to understand once and for all how I can write stored procedures that insert values in tables like this. I am using SQL Server and T-SQL and tried using SCOPE_IDENTITY() but that doesn't work since the table has INSERT_IDENTITY to false or off.
I'd really like to not insert a dummy value just to be able to insert a new row. Thanks!
If you have one column that is an IDENTITY, just do this
INSERT MyTable DEFAULT VALUES; --allows no column list. The default will be the IDENTITY
SELECT SCOPE_IDENTITY();
If you don't have identity, then can you set it? This is the best way.. and use the SQL above.
If not, you want to insert a new row
INSERT MyTable (admidid)
OUTPUT INSERTED.admidid --returns result to caller
SELECT ISNULL(MAX(admidid), 0) + 1 FROM MyTable
Notes:
Under high loads the MAX solution may fail with duplicates
SCOPE_IDENTITY is after the fact, not before
SCOPE_IDENTITY only works with an IDENTITY column. Ditto any idiocy using IDENT_CURRENT
The output clause replaces SCOPE_IDENTITY for the MAX solution
You need to add the IDENTITY_INSERT to your select statement:
SET IDENTITY_INSERT MyTable ON
INSERT INTO MyTable
(AdminCol)
SELECT AdminColValue
FROM Tableb
When you're done, make sure you remember to
SET IDENTITY_INSERT MyTable OFF
Here's a good description of how it works from BOL: http://msdn.microsoft.com/en-us/library/aa259221(SQL.80).aspx
#Phil: Don't you mean your table has two(2) columns, the autoincrementing PK column and an AdminName column? If it only has one column where the AdminName goes, the AdminName is the PK and you cannot autoincrement a string, of course. Do the business rules expect you to make a fully-qualified Windows username the primary key? That would be viable and make sense, because then you wouldn't need an alternate unique index on the AdminName column.
But if your table has two columns, not one:
In SQLServer the autoincrement is part of the table/column definition. You define the column as an integer and then also make it an
identity column, specifying the increment, usually 1, but it could be 2 or 5 or 10 or whatever. To insert a row, you simply insert the other column(s) value(s) and do nothing with the PK column:
insert into T
(foo) -- column(s) list
values('bar') -- values list
Your stored proc that does the insert can make SCOPE_IDENTITY a RETURN value or SCOPE_IDENTITY can be passed back to the client as an OUT parameter.
P.S. SCOPE_IDENTITY() returns the most recently generated autoincremented identity value in the current scope; it does not generate the next identity value.
EDIT:
Presumably, your Administrators table contains a set of administrators. But if it has no columns whatsoever other than the integer primary key column, there is no way to identify the administators; the only thing you can do is distinguish them from each other. That doesn't get you very far at all. But if your Administrator table had either of the following structures:
ID INTEGER PRIMARY KEY AUTOINCREMENT
windowsusername varchar(50) (unique index)
OR
windowsusername varchar(50) primary key
you would be able to reference the Administrator's table from other tables, and the foreign keys would be MEANINGFUL. And that's precisely what a table consisting of a single integer column lacks -- meaning.
Having two columns, you could then have a stored procedure do this:
insert into Administrators
(windowsusername)
values('mydomain\someusername');
return SCOPE_IDENTITY();
and your client-program would get back as a return value the autoincremented id that had been autogenerated and assigned to the newly inserted row. This approach is the usual practice, and I would go so far as to say that it is considered "best practice".
P.S. You mention that you didn't know how to "insert a value" if you "didn't have anything to insert". There's a contradiction there. If you have nothing to insert, why insert? Why would you create, say, a new CUSTOMER record if you know absolutely nothing about the customer? Not their name, their city, their phone number, nothing?