Get ID of the newly inserted record, using SqlDataAdapter - c#

BGREX.BGREXDataTable _bRexDataTable = new BGREX.BGREXDataTable();
BGREX.BGREXRow bgRexRow = _bRexDataTable.NewBGREXRow();
bgRexRow.BGRes_TITLE = "abc";
bgRexRow.BGRes_VERSION = 123;
_bRexDataTable.AddBGREXRow(bgRexRow);
int rewEffected = Adapter.Update(_bRexDataTable);
Have beed using above to insert record in Database, workes perfect. Now I need the id (Primary key) of newly inserted record which is auto generated, instead of rows affected to be returned from
Adapter.Update(_bRexDataTable);
It looks like I need SCOPE_IDENTITY() function, but I am not sure where to include this in designer as designers is not happy with following syntax added to the actual insert query.
It woks fine in sqlserver Management console though
DECLARE #ROWI_D int
INSERT INTO TABLE
.....
.....
.....
VALUES
("val1","val2",.......................)
SET ROW_ID = SCOPE_IDENTITY()

i'm not sure of a way to do this using sql statements with the commands. i'm not saying that it can't be done, i just never work with the statements, always through sprocs.
through the use of stored procedures you can define an output parameter which you can set equal to SCOPE_IDENTITY() in the sproc and then ensure that you pass that parameter into the command while settings it's direction as output.
sorry i don't have a solution for the direct sql call, but maybe someone else with more experience working in this way will chime in.
here's a link to a thread which discusses this same topic and a possible answer. but there's no verification whether the suggested solution worked or not.

Best way to do this is to change to a stored procedure that returns the value you want in a parameter. Post the code for doing the update you have now and I (or someone else) will show you how to refactor it to use a stored procedure. It is not hard.

Related

Entity Framework isn't getting the columns for Complex Type

The goal
I want to get for my complex types their respective columns.
The problem
Unlike this answer, by marc_s, in part (4) (four), my complex type have no database columns assigned to him.
To exemplify:
And before you ask, my function importing is right:
So, what I have to do?
Update 1
I have tried to add manually the properties to my complex type, but it is the best way?
Update 2
I want to add the scalars properties to my complex type automatically — like in the example I posted before.
#chiefGui I did not understand your question perfectly well, but seems when you click in "Get Column Information" button, you get no columns.
If it's that the problem you can fix it by adding a command in you procedure.
Put a command like this.
ALTER PROC ProcName /* ([,parameters] ) */
AS
BEGIN
/* this command you make the difference */
SET FMTONLY OFF
/* other code here */
END
Put this in first line of inside of your procedure. Remove the procedure from EDMX, add again and try again the import. And you'll get all columns returned by your procedure. So de step by step will working well.
If this is not the answer you want please add comment so I can help you.
EDITED
This happens because the EF try to getting columns headers without getting a result data. If your procedure has a high level of complexity, the EF will only be able to get the information, if your code is set to check the structure before running.
Did you notice that "Not Supported" caption next to the field name? Its because MySql connector can't fails to read datatypes from stored procedure resultset. This is a bug in MySQL Net Connector since forever. The work around is a create a table with the same two columns (in your example), import that table before importing the stored procedure into EDMX and when you import your stored procedure, in the Add Function Import dialog box, select "Entities" option instead of complex type, and map to that table.

C# + MySQL + ExecuteNonQuery returns '1' on UPDATE but changes not in DB

i have a problem where i can't apparently find a solution even after hours of debugging.
I have a simple SQL command where i want to update a row with some value(the value is a text of about ~5mb), after executing the SQL Command, the 'ExecuteNonQuery()' on the C# code side, returns '1' and no exception but the changes are sometime reflected in the Database row and sometime not.
I tried debugging to see if the values that will replace the old one are correct and they are. I am using MySQL 5.5.11.
Could it be a MySQL setting or something?
Losing my mind on this problem, if you have any idea it would be greatly appreciated.
EDIT, include code:
The code is as simple as this:
cmd.CommandText = "UPDATE user SET data = #data WHERE id = #id";
then i add params to the DBCommand object for the SQL Query. The 'data' is about ~5mb big.
this command always returns '1' even if the changes are not reflected in the database(sometime it works, sometime it doesnt):
cmd.ExecuteNonQuery();
Thanks in advance!
I don't know if the mysql provider uses autocommit? If not then you have to call commit on the Transaction object you can get with BeginTransaction on the connection object.
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.parameters.aspx
The Microsoft .NET Framework Data Provider for SQL Server does not support the question mark (?) placeholder for passing parameters to a SQL Statement or a stored procedure called by a command of CommandType.Text. In this case, named parameters must be used.
For example:
SELECT * FROM Customers WHERE CustomerID = #CustomerID
Edit:
Just noticed this was MySQL, and while i can't find anything simliar about it quickly, i would suggest you use named parameters anyways
I had this problem and it was related to autocommit.
Problem: earlier in the app lifespan autocommit was set to 0 by another process in the app, and failed. The connection with autocommit turned off is then reused by the connection pool.
That will lead to this type of error at unpredictable times.

C# database update

I'm stuck on a little problem concerning database.
Once a month I get a XML file with customer information (Name, address, city,etc.). My primary key is a customer number which is provided in the XML file.
I have no trouble inserting the information in the database;
var cmd = new SqlCommand("insert into [customer_info]
(customer_nr, firstname, lastname, address_1, address_2, address_3.......)");
//some code
cmd.ExecuteNonQuery();
Now, I would like to update my table or just fill it with new information. How can I achieve this?
I've tried using TableAdapter but it does not work.
And I'm only permitted to add one XML because I can only have one customer_nr as primary key.
So basically how do I update or fill my table with new information?
Thanks.
One way would be to bulk insert the data into a new staging table in the database (you could use SqlBulkCopy for this for optimal insert speed). Once it's in there, you could then index the customer_nr field and then run 2 statements:
-- UPDATE existing customers
UPDATE ci
SET ci.firstname = s.firstname,
ci.lastname = s.lastname,
... etc
FROM StagingTable s
INNER JOIN Customer_Info ci ON s.customer_nr = ci.customer_nr
-- INSERT new customers
INSERT Customer_Info (customer_nr, firstname, lastname, ....)
SELECT s.customer_nr, s.firstname, s.lastname, ....
FROM StagingTable s
LEFT JOIN Customer_Info ci ON s.customer_nr = ci.customer_nr
WHERE ci.customer_nr IS NULL
Finally, drop your staging table.
Alternatively, instead of the 2 statements, you could just use the MERGE statement if you are using SQL Server 2008 or later, which allows you to do INSERTs and UPDATEs via a single statement.
If I understand your question correctly - if the customer already exists you want to update their information, and if they don't already exist you want to insert a new row.
I have a lot of problems with hard-coded SQL commands in your code, so I would firstly be very tempted to refactor what you have done. However, to achieve what you want, you will need to execute a SELECT on the primary key, if it returns any results you should execute an UPDATE else you should execute an INSERT.
It would be best to do this in something like a Stored Procedure - you can pass the information to the stored procedure at then it can make a decision on whether to UPDATE or INSERT - this would also reduce the overhead of making several calls for your code to the database (A stored procedure would be much quicker)
AdaTheDev has indeed given the good suggestion.
But in case, you must insert/update from .NET code then you can
Create a stored procedure that will handle insert/update i.e. instead of using a direct insert query as command text, you make a call to stored proc. The SP will check if row exists or not and then update (or insert).
User TableAdapter - but this would be tedious. First you have to setup both insert & update commands. Then you have to query the database to get the existing customer numbers and then update the corresponding rows in the datatable making the Rowstate as Updated. I would rather not go this way.

How to get the primary key from a table without making a second trip?

How would I get the primary key ID number from a Table without making a second trip to the database in LINQ To SQL?
Right now, I submit the data to a table, and make another trip to figure out what id was assigned to the new field (in an auto increment id field). I want to do this in LINQ To SQL and not in Raw SQL (I no longer use Raw SQL).
Also, second part of my question is: I am always careful to know the ID of a user that's online because I'd rather call their information in various tables using their ID as opposed to using a GUID or a username, which are all long strings. I do this because I think that SQL Server doing a numeric compare is much (?) more efficient than doing a username (string) or even a guid (very long string) compare. My questions is, am I more concerned than I should be? Is the difference worth always keeping the userid (int32) in say, session state?
#RedFilter provided some interesting/promising leads for the first question, because I am at this stage unable to try them, if anyone knows or can confirm these changes that he recommended in the comments section of his answer?
If you have a reference to the object, you can just use that reference and call the primary key after you call db.SubmitChanges(). The LINQ object will automatically update its (Identifier) primary key field to reflect the new one assigned to it via SQL Server.
Example (vb.net):
Dim db As New NorthwindDataContext
Dim prod As New Product
prod.ProductName = "cheese!"
db.Products.InsertOnSubmit(prod)
db.SubmitChanges()
MessageBox.Show(prod.ProductID)
You could probably include the above code in a function and return the ProductID (or equivalent primary key) and use it somewhere else.
EDIT: If you are not doing atomic updates, you could add each new product to a separate Collection and iterate through it after you call SubmitChanges. I wish LINQ provided a 'database sneak peek' like a dataset would.
Unless you are doing something out of the ordinary, you should not need to do anything extra to retrieve the primary key that is generated.
When you call SubmitChanges on your Linq-to-SQL datacontext, it automatically updates the primary key values for your objects.
Regarding your second question - there may be a small performance improvement by doing a scan on a numeric field as opposed to something like varchar() but you will see much better performance either way by ensuring that you have the correct columns in your database indexed. And, with SQL Server if you create a primary key using an identity column, it will by default have a clustered index over it.
Linq to SQL automatically sets the identity value of your class with the ID generated when you insert a new record. Just access the property. I don't know if it uses a separate query for this or not, having never used it, but it is not unusual for ORMs to require another query to get back the last inserted ID.
Two ways you can do this independent of Linq To SQL (that may work with it):
1) If you are using SQL Server 2005 or higher, you can use the OUTPUT clause:
Returns information from, or
expressions based on, each row
affected by an INSERT, UPDATE, or
DELETE statement. These results can be
returned to the processing application
for use in such things as confirmation
messages, archiving, and other such
application requirements.
Alternatively, results can be inserted
into a table or table variable.
2) Alternately, you can construct a batch INSERT statement like this:
insert into MyTable
(field1)
values
('xxx');
select scope_identity();
which works at least as far back as SQL Server 2000.
In T-SQL, you could use the OUTPUT clause, saying:
INSERT table (columns...)
OUTPUT inserted.ID
SELECT columns...
So if you can configure LINQ to use that construct for doing inserts, then you can probably get it back easily. But whether LINQ can get a value back from an insert, I'll let someone else answer that.
Calling a stored procedure from LINQ that returns the ID as an output parameter is probably the easiest approach.

Best way to check whether a row has been updated in SQL

I have an update statement which updates a table. And there is a column that records the last modified time. If data in a specific row has not been changed, I don't want to change the last modified date time.
What is the best way to check whether an update statement will change the row of data or not.
Thanks,
Check the old vs. new data in your code instead of doing it in a query.
No need to bother the DB layer unnecessarily if data didn't change at all.
In short, if data didn't change, don't send the UPDATE statement.
One way is to start a transaction, select the contents of the row and compare it to what you're going to update it to. If they don't match, then do the update and end the transaction. If they match, rollback the transaction.
Sounds like you are going through a table and modifying some rows, then you want to go BACK through the table a second time and update the timestamp for the rows that were just changed.
Don't do it in two passes. Just update the date/time at the same time as you update whatever other columns you are changing:
UPDATE myTable
SET retailprice = wholesaleprice * 1.10,
lastmodified = GetDate()
WHERE ...
Or are you issuing an update statement on ALL rows, but for most rows, it just sets it to the value it already has? Don't do that. Exclude those rows that wouldn't be modified in your where clause:
UPDATE myTable
SET retailprice = wholesaleprice * 1.10,
lastmodified = GetDate()
WHERE retailprice <> wholesaleprice * 1.10
If you want to do this preemptively, the only way I can think of that you will do this is to modify the WHERE clause of the update statement to compare the existing value vs the new value (for EVERY value). If ANY of them are not equal, then the update should take place.
That's when a DAL is handy. It keeps track of all colums so if none changed then I don't even send an UPDATE statement to the database.
It depends on whether you have control of the data or not. Seb above is correct in saying you should check the old data against the new data before doing the update. But what if the data is not under your control?
Say you are a webservice being asked to do an update. Then the only way to check would be to query the existing data and compare it to the new data.
Don't know of any SQL functionality that would detect whether the update has actually changed any data or not.
There are ways in SQL to detect how many rows have been included in an update statement. Don't know of a way to detect whether an update statement actually changed any data, that would be interesting to know.
If you are using sql 2005/2008 then you can do as follows in the stored procedure.
update newTable
set readKey='1'
output inserted.id,
inserted.readKey as readKey,
deleted.readKey as prevReadKey
into #tempTable
where id = '1111'
Then you can select from #tempTable to verify if the prevReadKey and readKey has similar value if both has similar value you can reset your last modified datetime.
This way you don't have to fire multiple queries on the table in the case when a value is actually changing. But yes in the case when the value is not changing, this will be firing two update statements where none is required. This should be OK if those cases are rare.
P.S. NOTE:- The query given might be syntactically wrong as it is not tested. But this is the way your problem can be solved. I have done it in following way using OUTPUT clause with Merge statement in one of my project and it can be done with update statement too. Here is the reference of OUTPUT Clause
You COULD write an INSTEAD OF UPDATE trigger in T-SQL, where you could do what has been suggested above in the DAL layer -- compare the values in the existing record vs. the values in the update statement and either apply the update or not. You could use the Columns_Updated() function in the trigger to see if anything had been updated, and proceed accordingly.
It's not particularly efficient from the machine's point of view, but you could write it once and it would handle this situation no matter which application, stored procedure or other process was trying to update the record.

Categories