I'm applying ADO.net and want to add a new row to a DataTable placed in a DataSet. I then try to update the database with the new row by using the update method of a DataAdapter. The error I'm getting is
Column "RECORD_ID does not allow nulls.
RECORD_ID is the primary key column of my source table which has an autonumber datatype. I'm using MS Access 2007. Any ideas anyone how to solve this avoiding hacks?
Column RECORD_ID is primary key, that means it should have unique values different from null every time. You are adding dataRow to DataSet but forget to set the row["Record_ID"].
You need something like that:
row["RECORD_ID"]= Guid.NewGuid();//if RECORD_ID is type of GUID
row["RECORD_ID"]= LastUniqueID+1; // if RECORD_ID is int.
Related
I am trying to implement bulk insert of data from Datatable. In my MS-SQL Table(Destination table) i have a column with primary key not Identity column, so i have to increment manually. But its not possible in Code because there will be multi Thread on the same table.Please give me suggestion if any.
public void BulkInsert(DataTable dtTable)
{
DataTable dtProductSold = dtTable;
//creating object of SqlBulkCopy
SqlBulkCopy objbulk = new SqlBulkCopy(ConStr.ToString());
//assigning Destination table name
objbulk.DestinationTableName = "BatchData_InvReportMapping";
//Mapping Table column
objbulk.ColumnMappings.Add("InvPK", "InvPK");
objbulk.ColumnMappings.Add("DateValue", "DateDalue");
objbulk.ColumnMappings.Add("TextValue", "TextValue");
objbulk.ColumnMappings.Add("NumericValue", "NumericValue");
objbulk.ColumnMappings.Add("ErrorValue", "ErrorValue");
//inserting bulk Records into DataBase
objbulk.WriteToServer(dtProductSold);
}
Thanks in advance,
This is too long for a comment.
If you have a primary key column, then you need to take responsibility for its being unique and non-NULL when you insert rows. SQL Server offers a very handy mechanism to help with this, which is the identity column.
If you do not have an identity, then I you basically have two options:
Load data that has a valid primary key column.
Create a trigger that assigns the value when rows are loaded in.
Oh, wait. The default option for bulk insert is not to fire triggers, so the second choice really isn't a good option.
Instead, modify the table to have an identity primary key column. Then define a view on the table without the primary key and do the bulk insert into the view. The primary key will then be assigned automatically.
EDIT:
There is a third option, which might be feasible. Load the data into a staging table. Then insert from the staging table into the final table, calculating the primary key value. Something like this:
insert into finaltable (pk, . . .)
select m.maxpk + seqnum, . . . .
from (select row_number() over (order by (select null)) as seqnum,
. . .
from stagingtable
) s cross join
(select max(pk) as maxpk
from finaltable
) m;
i had one idea
generally we use tables to store the records, even if you insert the data using front end finally it will be stored in table.So i am suggesting to use sequences with insert trigger on the table. which means when you insert the data into the table first the trigger will be called, sequence will be incremented the the increased value will be stored along with other values in the table. just try this. because in oracle 11g we don't have identity() hence we will use sequences and insert trigger for identity column
Create a Table called id's. VARCHAR(50) TableName, INT Id.
When you want to generate your ids read the relevant row and increment it by the number of rows you want to insert within the same transaction.
you can now bulk insert these rows whenever you want without worrying about other threads inserting them.
Similar to how Nhibernates HiLow generator works.
http://weblogs.asp.net/ricardoperes/making-better-use-of-the-nhibernate-hilo-generator
I'm using sql server 2008 R2 and would like to apply unique key constraint to nullable columns. This code works good, but if I have multiple columns to add this rule to, it would generate as many 'nullbuster' columns.
ALTER TABLE tblBranch
ADD nullbuster AS (CASE WHEN column1 IS NULL THEN BranchID ELSE NULL END);
CREATE UNIQUE INDEX UK_Column1 ON tblBranch(column1,nullbuster);
Is there any way that I could achieve the goal without generating new columns.
EDIT:
Followed #marc_s suggestion, here to create an unique key constraint.
The target column is BranchCode. Now, there is one record in the table that has NULL for BranchCode. When I try to insert a new record, with Null BranchCode, from c#, it gives an error saying - Cannot insert duplicate key for unique index UK_BranchCode.
But, when I manually insert a record in the database, it does accept null values.
Where am I going wrong.
CS
Guid gId = Guid.NewGuid();
cmd = new sqlcommand("insert into tblBranch(BranchId,BranchCode)
values(#BranchId,#BranchCode)",con);
cmd.Parameters.AddWithValue("#BranchId",gId);
cmd.Parameters.AddWithValue("#BranchCode",txtBranchCode.Text);//empty text here
con.Open();
cmd.ExecuteNonQuery();
cmd.Close();
So you're creating a nullbuster column for each nullable column you want to index? Seems like overkill....
Wouldn't it be much easier to just create filtered indexes for those nullable columns, something like:
CREATE UNIQUE INDEX UK_Column1 ON tblBranch(column1) WHERE column1 IS NOT NULL;
and thus allow any number of NULL entries, while uniquely indexing the other values. That way, you don't need to add all those nullbuster columns just to make indexing possible...
Read more about filtered indexes:
Create Filtered Indexes (on Technet)
Introduction to Filtered Index – Improve performance with Filtered Index
Update: in order to set a parameter to NULL (and not an empty string), use this code:
if(string.IsNullOrEmpty(txtBranchCode.Text))
{
cmd.Parameters.AddWithValue("#BranchCode", DBNull.Value);
}
else
{
cmd.Parameters.AddWithValue("#BranchCode", txtBranchCode.Text);
}
Use the filtered index suggestion provided by marc_s. You say that you are still getting a unique index violation. What does that tell you? It tells you you are inserting a duplicate key with regards to the index definition. You think, you aren't, but you definitely are.
How to debug that? You look at what you are inserting. You look at gId and txtBranchCode.Text in the debugger. Also, you look at the error message, because it says:
The duplicate key value is ...
All of these clues lead you to find that txtBranchCode.Text is not null, but an empty string. Insert NULL instead.
I suggest you move column1 to a new table and make it unique and non-nullable. Reference the Branch table using a foreign key in the new table. Populate the new table only where you have a (non-null) value for column1.
Creating a new table is the surest way to support any dependencies on column1. A column that permits nulls is not a key column but column1 apparently should be. Putting that column into a new table also happens to be the only way to satisfy Normal Form and that ought to be the default approach unless you have a very compelling reason to "denormalise" column1 into the Branch table where it doesn't seem to belong.
I am using LINQ-to-SQL class. I am inserting a new row using LINQ method object.InsertOnSubmit().
I need to set same value which is generate by SQL Server (using Identity) for table primary key column.
Now I need the same value at the time of inserting new row into table. And set the same value for other column in the same table at the time of insert only.
As I cannot update as after inserting because table has UPDATE TRIGGER.
I tried the following
_db.EmpNews.InsertOnSubmit(_EmpNews);
...
_db.DisplaySeq = _EmpNews.ID;
...
_db.SubmitChanges();
Where ID is the auto-generated (Identity) column.
The first question really is: why would you need to store the same value in two separate columns in the same table? What do you need this for? Doesn't seem to make a lot of sense to me....
Since the value of the IDENTITY column is only available once the row has actually been inserted, there is no way to get that value and set it to another column before the row has indeed been saved to the database table.
That basically leaves three options to get that value and store it somewhere else:
you can write an AFTER INSERT trigger that just set the other column to the value that's just been inserted in the IDENTITY column
you could wrap the whole saving process into a stored procedure which you call from your C# code (instead of just saving the object) and you would do the INSERT of the row, then get the newly created IDENTITY value and update the row again with that new value. But that would cause an UPDATE to happen - which you seem to say is impossible for you because of an UPDATE trigger (not quite clear on why this should be a problem....)
you can write two lines of C# code to get the IDENTITY value after it's been inserted (and available in the ID property of your object) and then store the object a second time. But that, too, would cause an UPDATE to happen - which you seem to say is impossible for you because of an UPDATE trigger (not quite clear on why this should be a problem....)
So I guess your best option would be an INSERT trigger to do this.
Try something like this:
CREATE TRIGGER trInsertEmpNews
ON dbo.EmpNews AFTER INSERT
AS BEGIN
UPDATE dbo.EmpNews
SET DisplaySeq = i.ID
FROM INSERTED i
WHERE dbo.EmpNews.ID = i.ID
END
I'm trying to use a dataset to update some rows in a database, simple.
I'm creating a typed dataset instance, disabling constraints, adding a few rows to one table and populating a few of the columns in the rows, including the primary key, with existing and correct primary key values. Yet, when I call update on the data adapter it's throwing a primary key violation.
I'm not providing values for every column, only those I want to update. Why does the adapter not recognise an update is required?
MyDataset dataSet = new MyDataset();
dataSet.EnforceConstraints = false;
Simply because you Add() the records... That marks them as new and they will trigger an Insert statement on update.
I'm trying to insert a new row into a database which has four fields, the first is a primary key set as auto incrementing (integer) and the other three are strings.
I insert a new with the following statement:
INSERT INTO Manufacturer VALUES
('Test1','Test2','01332232321')
But I am given the following exception:
"SQLite error\r\ntable Manufacturer
has 4 columns but 3 values were
supplied"
I assumed that the primary key field can be omitted as the database would automatically assign and increment the value for me.
How would I go about fixing this? Is this a simple syntatical error or do I need to rethink my approach completely?
You have to specify columns:
INSERT INTO Manufacturer (col2, col3, col4) VALUES ('Test1','Test2','01332232321')
or pass the NULL value for primary key column.
I think you're looking for how to AUTOINCREMENT in sqllite
also How do I create an AUTOINCREMENT field