Update master/child rows - c#

I have tables Cases and Degrees with relation Cases.CID - CDegrees.CID. CID is Primary Key of Cases with AutoIncrement.
Both tables are used in one form and it's assumed that user can add new records to both tables same time and than save whole master/child data in one GUI action.
So in Dataset where I created FK I set "Both Relation and Foreign Key Constraint" to ensure during update of new record in Cases table, retrieved IDENTITY value will cause child records to update from -1 to retrieved CID value.
When I update Cases adapter, it causes to retrieve an new IDENTITY value and cascade update in CDegrees child record works ok too. But CDegrees's update causes Insert script with [CID]=-1 (original value). I changed Insert parameter #CID of CDegrees to "Proposed" version but same happens (seen in SQL Profiler).
Actually my task is mach more complicated, I just simplified task to localize my problem.
To describe more clearly.
before update
Both [Cases] and [CDegrees] have one new records with [CID]=-1
after [Cases] update both [Cases] and [CDegrees] have new CID identity value, just [CDegrees].[CID] "Current" value is -1 and "Proposed" is retrieved identity.
But when I call [CDegrees]'s dataset update, it sends Insert Command to SQL with [CID]=-1 regardless that I specified #CID parameter source as proposed value of [CID].

That is strange and funny. It appeared that calendar control on detailsform somehow causes but preventing details data cascade update according master identity value of CID field.
I just changed date field bound control from MonthCalendar to DateTimePicker and it worked.

Related

Insert to Oracle Database always creates new Index ID and doesn't take the old one

I am currently trying to insert a DataRow into an Oracle SQL Database. The entry gets inserted into the Database but always gets a new ID. I am providing an ID in the Insert Command but it always uses an auto increment and doesn't let me insert my ID.
What can I do?
There are 2 possible solutions to your problem.
Set column as NOT to be "Identity" column. This will take care of
your issue without any hassle.
If you must keep that column as "Identity" column, set "Generated"
property to "By Default on Null". This will ensure that when you are
NOT passing any value for ID, the system generates next sequence
number automatically.
For solution 2:
DDL Statement: ID NUMBER GENERATED BY DEFAULT ON NULL AS IDENTITY INCREMENT BY 1
Table Creation in SQL Developer:

How to detect which column's value has updated in a Table

Suppose I have a student registration form with 85 fields in my c# project and there are three buttons Save, Update, Delete.
The person who update the field knows very well that which field has updated but how other person will know that which field has updated ? Because...
If I click update button without changing any value, the Update query execute and the same update query execute too when I click update button with some changes.
So I want that database should detect which field has updated in update query.
The traditional way says that store the previous values and then compare them with new values one by one field. But this slow down the performance.
Any smart way ?
You can implement optimistic concurrent using a rowversion column. This avoids the need to check the old/new values of each column individually. Specify the original rowversion in the WHERE clause of the UPDATE statement and verify a row was updated. Proc example:
CREATE TABLE dbo.OptimisticConcurrencyExample(
OptimisticConcurrencyExampleID int NOT NULL
CONSTRAINT PK_OptimisticConcurrencyExample PRIMARY KEY
, Column1 int NOT NULL
, Column2 int NOT NULL
, Column3 int NOT NULL
, RowVersion rowversion
);
GO
CREATE PROC dbo.UpdateOptimisticConcurrencyExample
#OptimisticConcurrencyExampleID int
, #Column1 int
, #Column2 int
, #Column3 int
, #OriginalRowVersion rowversion
AS
UPDATE dbo.OptimisticConcurrencyExample
SET
Column1 = #Column1
, Column2 = #Column2
, Column3 = #Column3
WHERE
OptimisticConcurrencyExampleID = #OptimisticConcurrencyExampleID
AND RowVersion = #OriginalRowVersion;
IF ##ROWCOUNT = 0
BEGIN
RAISERROR('data updated or deleted by another user', 16, 1);
END
GO
When an optimistic concurrency error occurs, the app code can refresh the data with the current values, let the user know someone else updated the row, and allow the user to re-enter changes. You could get fancy and transparently merge pending changes in code (checking old/new values for each column) and notifying the user only if a conflict occurs. Similarly, you could present the user with a merge form after a conflict with the entered and current values side-by-side and the different values marked, etc.
But given conflicts are typically rare (unlikely that different users will update the same student record at the same time), the additional development effort may not be worth the trouble.
I have one way to do that thing using table versioning using that you can maintain every update, create, delete the record.
Tutorial for table versioning
Another Tutorial
The second way is you have to add audit table or field that store SQL query and also store which user change the data and also store last modified date like that.
Why do you need a save button and an update button? Same thing, right?
Modify the logic in your program to allow an update only if the user
changes the data on the student registration form relative to the
data in the database.
Read record from database
Store record data in a local DataRow or List
Load data onto the student registration form
update_button.enable = false
delete_button.enable = true
Create TextChange event methods for each TextBox on the student registration form
When a TextChange event method fires, compare the TextBox text to the corresponding DataRow field or List item (case
insensitive).
If they don't match, enable the update button
If the user clicks the update button, update the record and disable the update button

How Can I Programmatically Override the Auto_Increment Value When Inserting Into a DB

I have just started converting an old web application into a new structure.
I have a newly designed supplier table created in a MS SQL Server 2012 DB, which I am in the process of transferring the supplier data from the old DB to.
I have a C# MVC application set-up using the new DB as the data context. At present the application gets the data from the old applications DB, checks it, reformats it where necessary and inserts it into the new database in the desired format.
However as users of the application have got used to the supplier IDs in the old DB, I don't want to change the IDs, however as the id field in the new supplier table is an auto increment, it doesn't copy the ids from the old database. It just simply increments.
Does anybody know of anyway the auto increment can be overridden programmatically in the c# code for the initial import stage of the project. Once the data from the old system has been imported, I would then like to revert back to auto increment.
You can set identity insert on. However, if the users know the keys I've found they start asking to change them. I might consider the old keys as the user identifier and create a new surrogate key they won't ever see.
You can turn off the identity generation on the server temporarily during the bunch of inserts, then turn it on again. Try submitting this query to the server:
SET IDENTITY_INSERT dbo.sometable ON ;
INSERT INTO dbo.sometable (id,.......) VALUES (456,.......) ;
INSERT INTO dbo.sometable (id,.......) VALUES (276,.......) ;
INSERT INTO dbo.sometable (id,.......) VALUES (387,.......) ;
SET IDENTITY_INSERT dbo.sometable OFF ;
It just disables identity creation, then does the inserts (note that the column and value lists do include the id), then restores the default behavior.
In Sql Server, you can set the ID field to non identity. This will make it not auto increment

How to update autoincremented id when delete row in table?

I am creating application that uses MYSQL database in C#. I want to delete row and update autoincremented value of id in table. For example, I have table with two columns: id and station, and table is station list. Something like this
id station
1 pt1
2 pt2
3 pt3
If i delete second row, after deleting the table looks something like this:
id station
1 pt1
3 pt3
Is there any way that I update id of table, for this example that id in third row instead value 3 have value 2?
Thanks in advance!
An autoincrement column, by definition, should not be changed manually.
What happen if some other tables use this ID (3) as foreign key to refer to that record in this table? That table should be changed accordingly.
(Think about it, in your example is simple, but what happen if you delete ID = 2 in a table where the max(ID) is 100000? How many updates in the main table and in the referring tables?)
And in the end there is no real problem if you have gaps in your numbering.
I suggest you don't do anything special when a row is deleted. Yes you will have gaps in the ids, but why do you care? It is just an id.
If you change the value of id_station, you would also need to update the value in all tables that have an id_station field. It causes more unnecessary UPDATES.
The only way to change the value of the id column in other rows is with an UPDATE statement. There is no builtin mechanism to accomplish what you want.
I concur with the other answers here; normally, we do not change the value of an id column in other rows when a row is deleted. Normally, that id column is a primary key, and ideally, that primary key value is immutable (it is assigned once and it doesn't change.) If it does change, then any references to it will also need to change. (The ON UPDATE CASCADE for a foreign key will propagate the change to a child table, for storage engines like InnoDB that support foreign keys, but not with MyISAM.
Basically, changing an id value causes way more problems than it solves.
There is no "automatic" mechanism that changes the value of a column in other rows when a row is deleted.
With that said, there are times in the development cycle where I have had "static" data, and I wanted control over the id values, and I have made changes to id values. But this
is an administrative exercise, not a function performed by an application.

Inserting data into C# Datasets

I am using C#.Net application in which i created a dataset.Now i want to create a method in which i will enter a record in one table which will return a value ie primary key.Now by using that primary key i have to insert records in 5 tables and i have to use that primary key as a foreign key for this 5 tables using dataset.
You need to tell your parent table's table-adapter to refresh the
data-table after update operation.
This is how you can do that.
Open the properties of ParentTableAdapter -> Default Select Query -> Advnaced options. and Check the option of Refresh the data table. Save the adapter now. Now when you call update on table-adapter, the data-table will be updated [refreshed] after the update operation and will reflect the latest values from database table. if the primary-key or any coloumn is set to auto-increment, the data-table will have those latest value post recent update.
Now you can Call the update as ParentTableAdapterObj.Update(ds.dataTable);
Read latest values from the ParentDataTable(ds.dataTable) coloumns and assign respective values into the child table before update. This will work exactly the way you want.
alt text http://ruchitsurati.net/files/tds1.png
Have you tried temporary key linkage until the DB generates the final key? Works great for me.

Categories

Resources