1

I'm trying to update a certain column for each row in my SQL Server table, using ASP.NET, C#.

When this code is executed, I want the OrderNo of the first row in the column to be = 1. From then on, I want the OrderNo to increment by 1 for the other existing rows in the table.

At the moment, I can update the OrderNo of one row, however I can't get a loop to properly read through all the rows & increment as I would like.

Here is the structure of my table

Here

And below is my C#:

 con.Open();
 SqlCommand cmdUpdateOrderNo;
 cmdUpdateOrderNo = new SqlCommand("UPDATE tblImages SET [OrderNo]=@O WHERE [OrderNo] = 2;", con);
 cmdUpdateOrderNo.Parameters.AddWithValue("@O", 4);
 cmdUpdateOrderNo.ExecuteNonQuery();

Here is the reason I need to update the OrderNo:

  protected void Timer1_Tick(object sender, EventArgs e)
{
    int i = (int)ViewState["ImageDisplayed"];
    i = i + 1;
    ViewState["ImageDisplayed"] = i;
    DataRow imageDataRow = ((DataSet)ViewState["ImageData"]).Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == i.ToString());
    if (imageDataRow != null)
    {
        Image1.ImageUrl = "~/MyImages/" + imageDataRow["name"].ToString();
        lblImageName.Text = imageDataRow["name"].ToString();
        lblImageOrder.Text = imageDataRow["order"].ToString();
        lblImageDesc.Text = imageDataRow["Desc"].ToString();
    }
    else
    {
        SetImageUrl();
    }
}

private void SetImageUrl()
{
    DataSet ds = new DataSet();//Creating a dataset
    SqlDataAdapter da = new SqlDataAdapter("SELECT Name, [Order], [Desc] FROM tblImages", con);
    da.Fill(ds, "image");

    ViewState["ImageData"] = ds;//storing the dataset in a ViewState variable
    ViewState["ImageDisplayed"] = 1;//storing order number of the image currently displayed

    DataRow imageDataRow = ds.Tables["image"].Select().FirstOrDefault(x => x["order"].ToString() == "1");
    Image1.ImageUrl = "~/MyImages/" + imageDataRow["name"].ToString();
    lblImageName.Text = imageDataRow["name"].ToString();
    lblImageOrder.Text = imageDataRow["order"].ToString();
    lblImageDesc.Text = imageDataRow["Desc"].ToString();
}
5
  • 1
    Why the condition WHERE OrderNo = 2? This will limit the action to rows with OrderNo = 2 (probably just one) Commented Jan 4, 2017 at 13:45
  • 2
    Re-sequencing Order Numbers seems a weird, and potentially damaging, thing to do.Can you provide some context on why you would want to do this? Commented Jan 4, 2017 at 13:47
  • 2
    There's no need to go row by row when you can update the whole table using ROW_NUMBER for instance Commented Jan 4, 2017 at 13:47
  • @Steve Hi, that was just to check if my SQL was updating any row Commented Jan 4, 2017 at 13:56
  • @Jamiec I've added additional code above to help explain. I have a slideshow which displays these images. The order in which they appear is based on the OrderNo values. The slideshow begins at 1, and then increments to display further images. The problem is that if you delete an image in the middle of the table (i.e. where OrderNo = 3), the timer stops working after 2, because it cannot find 3. The reason to update this column is that when I delete OrderNo 3, OrderNo 4 is updated to 3 so the slideshow displays all the images Commented Jan 4, 2017 at 14:03

2 Answers 2

3

I agree with @Jamiec on this that it seems like a bad idea, but you don't need a loop if it's really what you want to do. Here's an example using a CTE and a Window Function.

Example

WITH T AS
    (   SELECT  
            *,
            ROW_NUMBER() OVER (ORDER BY ID) as RN
        FROM    YourTable
    )

/* this shows you the results of the CTE, 
   specifically the ROW_NUMBER() 
   which will replace the OrderNo in the code below */

SELECT * FROM T 

Runing This WIll Update Your Table

WITH T AS
(   SELECT  
        *,
        ROW_NUMBER() OVER (ORDER BY ID) as RN
    FROM    YourTable
)
UPDATE T
SET OrderNo = RN
Sign up to request clarification or add additional context in comments.

Comments

-1

When dealing with SQL you almost never want to be writing loops.

Try changing your command to this

; with cte as
(
    select *, row_number() over (order by ID) as rn 
    from tblImages
) 
update tblImages
set OrderNo = rn
from cte

3 Comments

once you have the CTE there's no need to do an INNER JOIN with the table, you can do the update as in @scsimon's answer
yeah, but this is essentially @scsimon's answer
Convergent evolution ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.