简体   繁体   中英

ms sql 2000 row_number code

I try write a SQL sintax for MS SQL 2000 with a row_number function... SQL 2000 doesn't support row_number with OVER, so I tried this code....

WHen I wrote this:

    SELECT P1.*,
            (SELECT COUNT(*) FROM Persons P2 
                   WHERE P2.Value<= P1.Value ) AS NewValue
             FROM Persons P1
    WHERE ...

everything is OK, a I get a new column 'NewValue' with row_numbers...

But, when I try to update one column in table with this new column, I always get an error:

"Derived table is not updatable because a column of the derived table is derived or constant..."???? What is wrong??

Here is a complete sintax:

    UPDATE t
    SET    t.Value= t.NewValue
    FROM   (SELECT P1.*,
            (SELECT COUNT(*) FROM Persons P2 
                WHERE P2.Value<= P1.Value) AS NewValue
             FROM Persons P1) t
    WHERE     ....

'Value' is a column in table which I can't update with a values from 'NewValue' column...

Thank you very much!!! :)

It means that SQL Server is unable to determine how to update the actual data. This error may appear in two cases:

  1. You're trying to update a constant field. Example:

     update T set Title = N'New title goes here' from (select 'Old title' as Title) as T 
  2. You're trying to update a derived value. Example:

     update T set MaxPrice = 512 from (select max(Price) as MaxPrice) as T 

In order to avoid this issue, you may consider adding a primary key to your table, or base your update on an unique index. There are few cases where you would need a table with no primary key or an unique index. If you're completely sure that any primary key or unique index will harm the schema, you may want to simulate the row_number , for example like this :

select 
    RowNumber = identity(int, 1, 1),
    c.LastName,
    c.FirstName
into #Customer_RowID
from SalesLT.Customer c
order by c.LastName asc

Given the lack of unique constraint, make sure you do the select-update within a transaction to avoid updating a different row.

You should shift things around and do your counting directly as a subquery in the SET clause:

UPDATE P1
SET    Value= (SELECT COUNT(*) FROM Persons P2 
            WHERE P2.Value<= P1.Value)
FROM   Persons P1
WHERE     ....

I am not sure why this syntax doesn't work in SQL Server 2000. I'm pretty sure the syntax would work in more recent versions of SQL Server.

Perhaps you should consider upgrading to a supported product.

This version might work:

   UPDATE Persons
     SET t.Value =  (SELECT COUNT(*) FROM Persons P2 WHERE P2.Value <= Persons.Value)
     WHERE     ....;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM