SQL Server 2000 - Update rows and return updated rows - sql

I am wondering how to rewrite the following SQL Server 2005/2008 script for SQL Server 2000 which didn't have OUTPUT yet.
Basically, I would like to update rows and return the updated rows without creating deadlocks.
Thanks in advance!
UPDATE TABLE
SET Locked = 1
OUTPUT INSERTED.*
WHERE Locked = 0

You can't in SQL Server 2000 cleanly
What you can do is use a transaction and some lock hints to prevent a race condition. Your main problem is 2 processes accessing the same row(s), not a deadlock. See SQL Server Process Queue Race Condition for more, please.
BEGIN TRANSACTION
SELECT * FROM TABLE WITH (ROWLOCK, READPAST, UPDLOCK) WHERE Locked = 0
UPDATE TABLE
SET Locked = 1
WHERE Locked = 0
COMMIT TRANSACTION
I haven't tried this, but you could also try a SELECT in an UPDATE trigger from INSERTED.

Related

UPDATE statement under a transaction running indefinitely

I am facing issue with ever-running query in one stored procedure (using SQL Server 2005).
In this stored procedure there are many UPDATE statements and few INSERT statements running under one Transaction.
When debugging the stored procedure, I found that there is one specific UPDATE query which is running indefinitely as shown below.
BEGIN TRAN
...
...-- some INSERT & UPDATE statements
UPDATE PIH
SET PIH.RemittanceHeaderID = RD.RemittanceHeaderID
FROM TempPayroll TP
INNER JOIN RemittanceDetails RD ON TP.UniqueID = RD.PLInvoiceDetailID
INNER JOIN PLInvoiceHeader PIH ON RD.PLInvoiceUniqueID = PIH.InvoiceUniqueID AND PIH.CompanyCode = TP.CompanyCode
WHERE TP.PLSelfBill = 1
AND TP.UsePLPaymentTerms = 1
AND RD.PLInvoiceDetailID IS NOT NULL
AND TP.RecordType LIKE 'INVOICE%'
AND RD.RecordType LIKE 'INVOICE%'
... --some UPDATE statements
COMMIT TRAN
However, when I remove the CompanyCode condition the stored procedure is working fast with no issues. Also if I execute just this statement alone under a transaction separately it is running fine.
There are around 240 matching records for this query. Each table contains just 30k - 50k records.
How do I debug the query and how to fix it?
Why just that JOIN condition (CompanyCode) is creating this issue?
Thanks in advance.

##ROWCOUNT check not detecting zero row count

I have a SQL Server Stored Procedure (using SQL Server 2008 R2) where it performs several different table updates. When rows have been updated I want to record information in an Audit table.
Here is my pseudo code:
UPDATE tblName SET flag = 'Y' WHERE flag = 'N'
IF ##ROWCOUNT > 0
BEGIN
INSERT INTO auditTable...etc
END
Unfortunately, even when zero rows are updated it still records the action in the audit table.
Note: There are no related triggers on the table being updated.
Any ideas why this could be happening?
Any statement that is executed in T-SQL will set the ##rowcount, even the if statement, so the general rule is to capture the value in the statement following the statement you're interested in.
So after
update table set ....
you want
Select #mycount = ##Rowcount
Then you use this value to do your flow control or messages.
As the docs state, even a simple variable assignment will set the ##rowcount to 1.
This is why it's important in this case that if you want people to diagnose the problem then you need to provide the actual code, not pseudo code.

Encountering deadlock while deleting and running update statistics

I am running a stored procedure that deletes data from a table, the procedure looks like:
SET rowcount 10000
WHILE ( #rows_deleted > 0 )
BEGIN
BEGIN TRAN
DELETE TABLE1 WHERE status = '1'
SELECT #rows_deleted = ##rowcount
COMMIT TRAN
END
While this procedure is running, update statistics is also running on the same table.
The table's lock scheme is all pages.
I am wondering if the locking is all pages how can it encounter a deadlock?
There is nothing else running on this table.
I am using Sybase 12.5 ASE
Found out that update statistics indeed was creating the deadlock. It was taking a shared lock on the table. As the table has locking scheme of all pages, the delete would have to wait for it to complete. But instead of blocking delete query for long time, Sybase chooses to terminate it as the victim.

Sql delete not appearing to work

I am running delete sql in Managment Studio 2008 and it indicated to me the sql has worked....but it hasnt.
For example
select count(*) from MyTable where [MYkey] =24
returns 1
delete from MyTable where [MYkey] = 24
Rows Affected 1
But if I immediately run the first statement again, the record is still there. If I try an update statement, that works. I am seeing this behaviour on all tables in the database.
I had a few issues with the Transaction log being full a few days ago, I change the recovery model to simple. Could this be related? If so what do I need to do?
Try this -
BEGIN TRANSACTION;
delete from MyTable where [MYkey] = 24;
COMMIT TRANSACTION;

How to detect a record is locked?

With SQL Server 2008, how can I detect if a record is locked?
EDIT:
I need to know this, so I can notify the user that the record is not accessible because the record is blocked.
In most circumstances with SQL 2008 you can do something like:
if exists(select 0 from table with (nolock) where id = #id)
and not exists(select 0 from table with(readpast) where id = #id)
begin
-- Record is locked! Do something.
end
If that is not enough (that is, you need to ignore table-level locks as well), use the NOWAIT hint that throws an error if there's a lock.