I have a table wherein I want to update a rows individually:
Transaction ID EmpID START END LOGDATE
1 1 8:32:32 NULL 7/25/2016
2 2 9:02:10 NULL 7/25/2016
3 3 9:00:56 NULL 7/25/2016
4 3 9:42:00 NULL 7/26/2016
5 2 10:58:00 NULL 7/26/2016
6 1 9:23:00 NULL 7/26/2016
If I use this:
UPDATE EmpLog SET ShiftEnd = '09:00:00' WHERE EmpID = 1 and CONVERT(date, EmpLog.LogDate) = CONVERT(date, GETDATE())
I can only update the specific row within the day, but since I need to be able to account for overtime, it can't be.
How do I update a specific row to update the END column for a specific transaction with C#?
Basically, the layout of my C# program is that a user must input his EmpID, and press 'START' or 'END'. but the 'END' part is tricky. I ended up updating all rows and losing previous data.
How do I update a specific row with the latest transaction ID for each specific employee? Sorry If i'm confusing.
I read your question like this:
I want to update the last entry for a specific employee
As long as the transaction id will increase for every entry, you could do something like this:
UPDATE EmpLog
SET ShiftEnd = '09:00:00'
WHERE EmpID = 1 AND [Transaction ID] =
(SELECT MAX([Transaction ID]) FROM EmpLog WHERE EmpID = 1)
Read this similiar question:
Is it possible to use MAX in update statement using sql?
This is for MS SQL Server mainly, but I think you can easily translate it to mysql. There may be an even better way in mysql.
Downside with this solution: You have to make an extra select in your update, which will be slower, but for this example if think it should do fine.
Related
I have multiple tables in my SQL Server database.
I have one table [Tatkal_Merge] which has fields like filename,C_srno,Scan,etc. [c_srno is the secondary key]
The second table Collation_Data has details like srno,filename, dispatchcount, totalcount etc. [srno is the primary key]
The totalcount is the total number of records in tatkalmerge table.
There are many other fields in both tables but not relevant to this question.
Whenever the customer scans a barcode in winForm and the update is successful I update [Tatkal_Merge] with scan value 'Y' and increment the Collation_Data dispatch count using stored procedure
update [Tatkal_Merge] set [DScan]=#scan,[DScanBy]=#scanBy,[DScanTime]=getdate() where Dscan='N' and [wl_barcode]=#wl
if(##ROWCOUNT=1)
update Collation_Data set Dqty=Dqty+1 where srno=#C_srno
Issue
Sometimes due to some reason the Dispatch count is not correct by 1 or 2 customers.
Requirement:
1) Please guide why there is a discrepancy in the count. My guess is network issue between first and second command.
2) If am doing it the wrong what is the correct way of doing this?
3) If am doing it the right how to update the Table B in such scenario?
P.S.
Currently, I am updating the collation_Data using correlated subquery periodically,
update Collation_Data c
set Dqty = (select count(*)
from [Tatkal].[dbo].[Tatkal_Merge] m
where m.Dscan = 'Y' and m.collation_code = c.collation_code
);
Few things you can do to isolate and troubleshoot:
Enclose both updates inside a transaction
Trap the ##ROWCOUNT on second update and if that is = 0 it means that the update wasnt succesfull and you could write all the important fields and variables into a logging table that might lead you to the culprit.
The main reason why the second update would fail would be if the ##ROWCOUNT from the first update was <> 1 or if it didnt find any row for that srno. Unlikely that it is a network issue.
if(##ROWCOUNT=1)
this might be an issue if there are more matching rows to the first update of table [Tatkal_Merge]. Instead change it to:
if(##ROWCOUNT > 0)
update Collation_Data set Dqty=Dqty+1 where srno=#C_srno
I'm using EF in order to insert and retrieve info from DB,
there is any way to insert new row but at the specified position,
Like i have 10 rows with IDs ranging from 0 to 9 and new row i'm inserting will be on the position 4?
I'm using ASP.NET MVC 5 and LINQ.
Thank you.
The simple answer is no. Order has no meaning unless it's explicit in a database system. Sure in most cases I can insert into a table and pull from this exact table and get the exact order as it was inserted, but this is undefined...and the only guarantee is to use an ORDER BY clause.
If you are talking about changing an auto number property, this is also not possible, the database does not go back and fill in gaps with id numbers. If numbering is critical and important to you don't set the auto-increment property.
Your ID and order position are different things.
For ID you use an autonumeric and you shouldnt mess with that.
For order you use another column and run a trigger when a new row is insert update all the rows
So when the new row is inserted with order_id = 4 all the rows get update
something like
UPDATE table
set order_id = order_id +1
when order_id >= 4
So, I would do so quickly:
I would plan the database to not auto increment primary key and saving would so that the id is attributed according to the specific location. Obviously put an IF to verify that it is available, and if I would start a review cycle to the cascade of subsequent ID or positioning the value traded in the end.
for example
MyTable table = myDb.MyTable.Find(id); //position
if (table==null)
{ table.id=position; table.Field=value; myDb.SaveChanges() }
else
{
var temp = table.id;
var max = table.count(x=> x.id).value;
table.id=max+1;myDb.SaveChanges();
table.id=id; table.Field=value; myDb.SaveChanges();
}
sorry if translate is no good! ;-)
I want to get a new row id for "products", for this I use MAX SQL command as follwing (the command is in insert new record button click event):
SqlCommand cmd = new SqlCommand("Select ISNULL(MAX(id)+1,0) from products", SqlCon);
the issue is when there are rows with IDs 10,11,12 (12 is MAX) and i delete id 12 record , i gets MAX+1 id 12 when the new id row is 13 ("id" field is PK with identity increment 1).
can i do it with other way?
example:
id prodect
-- -------
1 dog
2 cat
3 mouse
4 elefant
when i deletes row 4 i get MAX(id)+1 = 4 and i want to get 5 since this is the next row id.
I suspect the actual question is How can I find the ID of the row I just inserted so I can use it as a foreign key in related tables or in an image file name?
SQL Server since 2005 provides the OUTPUT clause in INSERT, UPDATE, DELETE statements that returns the values of the columns just inserted or modified. In the case of the insert statement, the syntax is:
insert into Products (Product)
OUTPUT inserted.ID
VALUES ('xxx')
This is a better option than the IDENT_CURRENT or SCOPE_IDENTITY values because it returns the values using a single statement and there is no ambiguity about what is returned:
IDENT_CURRENT may return a different value if multiple users are writing to the table outside a transaction
SCOPE_IDENTITY returns the last ID generated in a transaction, no matter the table
You can return more than one column:
insert into Products (Product)
OUTPUT inserted.ID, inserted.Product
VALUES ('xxx')
You can execute this statement with ExecuteScalar, if you return only one column or ExecuteReader, if you want to return more columns.
In the case of UPDATE or DELETE statements, the deleted table contains the deleted values and inserted contains the new values
Note ORMs like Entity Framework use such statements already to retrieve auto-generated IDs and update saved objects. In this case one only needs to read the ID property of the saved objects.
I will take a stab at what I think you are after. :)
If you include SELECT SCOPE_IDENTITY(); in your SQL you will get the ID you need:
INSERT INTO products (
* your fields *
)
VALUES (
* your values *
);
SELECT SCOPE_IDENTITY();
And then in your code you can have:
var Id = Convert.ToInt32(cmd.ExecuteScalar());
This will give you the id of the record you have inserted.
One possible solution could be that you don't delete the rows. You can add a flag and make it inactive/deleted. That way your row numbers will always be preserved and your code will give you the max Id.
I think the OP tries to tackle the wrong problem...
When you insert a new product into the products table, you should try to retrieve the new id directly with the scope_identity function as such (SQLServer!):
string sql = "insert into products(name) values('Yellow Cup'); SELECT SCOPE_IDENTITY();";
var sqlCommand = new SqlCommand(sql, conn);
var id = cSqlServer.ExecuteScalar();
Definitely MAX is not what anybody would use in this case. Closest solution would be to get recently used identity value and then increment it by 1 (in your case) or by seed value, whatever it is.
select ident_current('products') + 1
Caution - although this solves your purpose for now, beware that 'ident_current' will return you the identity value set by other sessions as well. In simple words, if there is some request/trigger/execution that causes id to be incremented even before your button click finishes then you you will get inserted_id and not deleted one.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have inserted 4 records into table1, and then 5 records and then 3 records.
Now I want to pick up last 3 records or say any number of records but inserted at last. How I will get those ?
Actually scenario is that in gridview 1 user would select say 3 records by help of checkbox field and then these 3 records will be inserted in to table1 and then store procedure will pick these last inserted 3 reocrds and assign it to RDLC report. All things are done but just don't know how to pick last inserted any number of records.
By definition, a table is an unordered set of rows. There is no way to ask SQL Server which row was inserted last unless you are doing so in the same batch as the insert. For example, if your table has an IDENTITY column, you can say:
INSERT dbo.table(column) values (...)
SELECT SCOPE_IDENTITY();
But that too will give you the last first identity column.
What you can do here is that you can take the help of timestamp and define that in a separate column of the table.
ALTER TABLE dbo.table ADD DateInserted DEFAULT CURRENT_TIMESTAMP;
Define stored procedure with the #lastrows count that you will store in your service layer to call.
CREATE PROC sp_GetLastInsertedRows(#lastrows int)
AS
;WITH x AS (SELECT *, r = ROW_NUMBER() OVER (ORDER BY DateInserted DESC)
FROM dbo.table)
SELECT * FROM x WHERE r <= N;
This way you get the last N number of rows inserted in the last transaction.
you can use below menioned query
SELECT column_name FROM table_name
ORDER BY column_name DESC
LIMIT 3;
Okay, so you're going to need something a bit more flexible. Right now you may have just one user, and right now you may be running the report immediately after executing the INSERT statements, but what you really need to know is what rows are new since the last time you looked.
One good way of doing this is adding a DATETIME NULL field to the row; let's call it processed_date. This field will be updated by the stored procedure that picks them up for the report. Something like this:
SELECT * FROM tbl1
INTO #report_tbl
WHERE processed_date IS NULL
UPDATE tbl1
SET processed_date = GETDATE()
WHERE id_field IN (
SELECT id_field
FROM #report_tbl
)
Now you are sure to pick up the rows that "haven't been looked at."
Im working on database synchronization in my app. It means I have 5 databases, but:
only in first database product could be added/removed/modified
this first database saving information about added/removed/modified product to table (with flag 1/2/3 as add/edit/remove and productID)
so first database generates INSERT script from SELECT, for example:
in my product_changes table (addedRemovedEdited INT, productID INT) I have information:
1, 15 (1 - flag means product with ID = 15 was added), or
2, 15 (2 - flag means product with ID = 15 was edited) etc.
Now using this information I can create script - and there is problem.
At this momment im creating scripts like:
SELECT (col1, col2, col3,...) FROM Product_Category;
string query = "INSERT INTO Table VALUES (#a,#b,#c)...";
SELECT (col1,col2,col3,...) FROM Product_price;
query += "INSERT INTO .......";
And I need to do it foreach tables which contains information about one single products. So for 10 products I'll have 10 * 12 (12 because there is ~12 tables about one product) blocks of code like INSERT INTO Table 1(....); INSERT INTO TABLE2(....).
Problem is also that, all data need to have same ID in every databases - so I'm using ##identity and put it into insert query. It has to be this way, because product with ID = 10 with name 'Keyboard' in mainDB = product with ID = 10 in DB10.
And the question - maybe some of you know any better (becouse that one is not so good) solution how can I create those scripts? Like query, which will take all information from my string[] a = {"Product", "Product_price", "Product_category"} tables and generate INSERT queries but - most important - where I can add ##identity.
#EDIT: I forgot. I found that solution: how i can generate programmatically "insert into" data script file from a database table?
Well, it does generate scripts, but with auto-incremented ID. And I need to add information in right order (as middle tables) for example:
INSERT INTO Product(.....) VALUES (...);
SET #pID = ##identity FROM Product;
INSERT INTO Price (priceID,.....) VALUES (...);
SET #prID = ##identity FROM Price;
INSERT INTO Product_price (priceID, productID,...) VALUES (#prID, #pID)