I'm trying to insert data into my database by using a stored procedure but 3 of my columns are using the int identity type and I cannot insert. It keeps saying cannot do this whilst identity insert is off
When IDENTITY_INSERT is on, it just means that you can put your own data in IDENTITY column. It doesn't disable the FK constraint you have on the table. You can delete the FK constraint, or disable it, and risk having logically inconsistent data in your DB, or you can fix your SP so you won't insert any duplicate values.
Something is amiss. Three columns in a single table of type Identity? I'm having difficulty imagining what they could represent, and I have to wonder where the natural keys are.
In any case, IDENTITY_INSERT isn't something you want to putz with casually. It's an administrative feature to allow ad hoc changes to the data, for example bulk loading the database.
If you do actually know what the identities are (as input to your stored procedure) then the table is misdefined, because it's supposed to be the identity source. If you don't know, or you're willing to let the table generate identity values, then you simply don't mention those columns in your INSERT statement. At most, the generated values would be OUTPUT parameters to your stored procedure.
Related
I am migrating data from one database to another. I have my scripts mostly together already, but I am trying to figure out the best way to make one change to a table in the new database.
I have a Customer table. That table has a customer_id column which is the identity column. I want to change the identity seed/increment from (1,1) to (200,1) without changing the customer_ids for the existing data I will be inserting into the table.
Old data is 101-108. Basically we want to keep the old data the same so it matches up with old records in other systems, but we want the new data to start seeding in at 200.
I tried Googling how to do this, but all my Googling came back with results where people wanted to change what column was the identity column, and not just change the identity seed number. Is there a simple query I can use to accomplish what I want to do?
You can use DBCC CHECKIDENT:
DBCC CHECKIDENT ('dbo.customer', RESEED, 200)
This will change the current seed value of the identity column of the specified table. If you need to insert specific identity values, you can SET IDENTITY_INSERT ON in your insert statement.
IDENTITY_INSERT
What I would do unset the new column as an identity (using alter table), then insert the data from the old table, and then reset the new column as the identity again, with whatever increment you want as per the link
https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql-identity-property?view=sql-server-2017
I am new to SSIS packages and just require assistance on how to transfer data from one data source onto my own database.
Below is my data flow:
Now I have a ODBC Source (Http_Requests Source) where I take data from a PostgreSQL database table (see screenshot below for table columns and data):
Below is the OLE DB destination where it has the table I want to transfer the data to (this table is currently blank):
Now I tried to start debugging to extract the data but I get a few errors (displayed below):
I am a complete novice so I would like some guidance on what I need to include in order to get this SSIS package to transfer data across. Would I need to include a merge statement and how do I apply it. I heard you can write a merge as a proc and call on the proc as a sql command. Does that mean I will need to write a proc in SSMS and then call on it within the OLE DB Destination?
If somebody can provide an example and screenshot then that would be very helpful as I am really new to SSIS.
Thank you,
Check constraint on destination table or disable them before running it.
Below are query you can use.
-- Disable all table constraints
ALTER TABLE YourTableName NOCHECK CONSTRAINT ALL
-- Enable all table constraints
ALTER TABLE YourTableName CHECK CONSTRAINT ALL
Tick keep identity
box or drop primary key on the table. After you apply the changes do not forget to refresh metadata by opening the mappings in sis.
the error means that PerformanceId is an IDENTITY column on your destination table. IDENTITY columns are read only unless you tell it otherwise. So if we were in tSQL to be able to insert IDENTITY we would turn on IDENTITY_INSERT. Because you are in SSIS you can accomplish the same thing by checking the "keep identity" box.
HOWEVER when ever you get an error like this it is usually a sign that you should NOT be mapping ID to Performance ID. The question you have to ask is the Identity from your source supposed to be the identity of the destination table? Usually not, most of the time it would be another column as a surrogate key. Then you have to understand if it is even possible. because if there is a unique constraint or primary key then the identity cannot repeat which means you have to know that your source's id column will not cause a duplicate primary key violation.
More than likely the actual fix if for you to uncheck ID from the source and ignore the value.
The column PerformanceID (in the target) is almost certainly an identity column and that is why it is not working. You may not want to transfer it (and have SQL Server generate values for PerformanceID or you can check 'Keep Identity.'
With SQL, when inserting values into a Table from a SP, is it possible to get the value of the Primary Key before the values are added to the Table?
This is certainly possible, leveraging the power of relational databases. Assuming, like Martin Smith said, that you are using an autogenerated key, then you can use a transaction to do what you're looking for.
Here's the general idea:
Start a transaction.
Do the insertion.
Use the primary key to do whatever you need to do, including updated the inserted row to reflect the value.
Commit or rollback
By beginning a transaction before your insert, you can assure that no one else will be able to see the new rows until you commit your transaction. If the key is not to your liking, you can rollback the transaction, and no one else will know. If the key is adequate, you can modify the rows you have just inserted before committing.
Since you have a transaction, no one else can see the intermediate data you have inserted before you commit. Thus, you can update the rows that you have just inserted as if you have the primary key before your actual insert.
If you are using SQL Server the best way to do this is with your MERGE or INSERT command use the OUTPUT clause to get your key back. Even though this is not before the insert you can use the results of the OUTPUT to join back the results of your data to insert subsequent children records.
Also if you are using SQL server you can look at IDENT_CURRENT function which will return the current identity value of a table. If you are writing your SQL in a set based fashion the OUTPUT that I mention above works best for me.
I have a pair of databases, one is a live database and one is for testing a configuration for that live database. Both reside on the same server.
I have three tables, Users (PK UserId, FK MainGroupId) and Groups (PK GroupId) and GroupMembers (PK GroupMemberId, FK GroupId and UserId).
The tables are the same schema on both databases however the test database has a set of special test users. Groups is mostly stable, but sometimes we add groups, and sometimes we change column data in the groups. GroupMembers is the same but in the test database refers to the test users.
I need to be able to update the Groups table from the live to test user programmatically. I want to use a bulk copy operation, but to do so I have to delete the Groups table first, which will cause a constraint violation.
I could copy the table in bulk to a dummy table, and then post process by doing an insert of the new rows, and update on the existing rows. However, my problems is that there are about 30 tables like Groups, and I don't want to encode all the column names into the stored procedure in the UPDATE SET method. I'd also like to be able to do it in bulk.
The DBAs are dubious about granting ALTER TABLE permission to temporarily drop the constraints.
Any other suggestions?
SInce both databases are on the same server, why not use a MERGE statement?
select for export and import. If you do it in the right order it should work correctly.
Ever since I cleaned the data on the SQL Database I've been getting this issue, whereas on the unclean database the issue does not happen. When I run my stored procedure (huge procedure) it returns:
General SQL error. Cannot insert duplicate key row in object 'dbo.TitleClient' with unique index 'XAK1TitleClient'. Cannot insert the value NULL into column 'id_title', table 'Database.dbo.TitleCom'; column does not allow null, insert fails.
Is it possible that I deleted data from a table that causes this? Or is that impossible?
Does dbo.TitleClient have an identity column? You might need to run
DBCC CHECKIDENT('dbo.TitleClient')
I'm guessing that the first message
Cannot insert duplicate key row in
object 'dbo.TitleClient' with unique
index 'XAK1TitleClient'
is because the seed value is out of synch with the existing table values and the second error message
Cannot insert the value NULL into
column 'id_title', table
'Database.dbo.TitleCom' column does
not allow null, insert fails.
Comes from a failed attempt at inserting the result of scope_identity from the first statement.
How cleanly did you "clean" the data?
If some tables still have data, that might be causing a problem.
Especially if you have triggers resulting in further inserts.
For you to investigate further.
Take the body of your stored proc, and run it bit-by-bit.
Eventually, you'll get to the actual statement producing the error.
Of course if you aren't inserting into dbo.TitleClient at this point, then it's certainly a trigger causing problems.
Either way: Now you can easily check the data inserted earlier in your proc to figure out the root cause.