Note that there are some explanatory texts on larger screens.

plurals
  1. POPostgreSQL, drag and swap
    primarykey
    data
    text
    <p>I have successfully solved situation regarding swapping rows by value <a href="https://stackoverflow.com/questions/18250750/postgresql-advanced-swapping">here</a> what still work excellent.<br> But by using this function I see some lacks of functionality in mean of drag and drop rows.<br> I try to get solution <a href="https://stackoverflow.com/questions/14085258/how-do-i-get-a-column-with-consecutive-increasing-numbers-without-having-any-n/14092775#14092775">here</a> where discussion goes wrong way and offered solution is not adequate since they need additional columns. </p> <p>Here is well known table: </p> <pre><code>DROP TABLE IF EXISTS kalksad1; CREATE TABLE kalksad1( kalk_id int PRIMARY KEY, brkalk integer, brred integer, description text); INSERT INTO kalksad1 VALUES (12, 2, 5, 'text index 12 doc 2 row 5'), (26, 2, 1, 'text index 26 doc 2 row 1'), (30, 2, 2, 'text index 30 doc 2 row 2'), (32, 4, 1, 'text index 32 doc 4 row 1'), (36, 1, 1, 'text index 36 doc 1 row 1'), (37, 1, 2, 'text index 37 doc 1 row 2'), (38, 5, 1, 'text index 38 doc 5 row 1'), (39, 5, 2, 'text index 39 doc 5 row 2'), (42, 2, 3, 'text index 42 doc 2 row 3'), (43, 2, 4, 'text index 43 doc 2 row 4'), (46, 3, 1, 'text index 46 doc 3 row 1'), (47, 3, 2, 'text index 47 doc 3 row 2'); </code></pre> <p>Object of manipulation is reordering values of column "brred"(row) under same "brkalk"(doc).<br> Let "brkalk" be 2. </p> <p>Now I would like to get reordering/swapping according to drag and drop needs where swapping just one row look unnatural. I have datagrid binded to kalksad1 table so I will describe situation looking in my datagrid filled with query "... ORDERED by brred". </p> <p>If I could explain query by words that would be...<br> Example 1:<br> <em>Under doc 2 I will drag row 4 and drop it to position of row 2.</em><br> For that is needed following steps:<br> 1) Remember data of row 4.<br> 2) In row 3 replace value of "brred" from 3 to 4.<br> 3) In row 2 replace value of "brred" from 2 to 3.<br> 4) In remembered data from step 1) change value of "brred" from 4 to 2. </p> <p>Example 2:<br> <em>Under doc 2 I will drag row 1 and drop it to position 3.</em><br> That can go like this:<br> 1) Remember data of row 1.<br> 2) In row 2 replace value of "brred" from 2 to 1.<br> 3) In row 3 replace value of "brred" from 3 to 2.<br> 4) In remembered data from step 1. change value of "brred" from 1 to 3. </p> <p>Idea that this may be possible comes from elegant solution with swapping and SO questions <a href="https://stackoverflow.com/questions/6037045/resequencing-a-column-with-identifier-in-postgresql">like this</a>, <a href="https://stackoverflow.com/questions/6725783/postgresql-record-reordering-using-update-with-a-sub-select">this</a> and <a href="https://stackoverflow.com/questions/3397121/how-to-show-row-numbers-in-postgresql-query">this</a>. I make examples based on my thinkings but that shouldn't go that way if better exist.</p> <p>Please if someone can write described query at way similar to those for <a href="https://stackoverflow.com/questions/18250750/postgresql-advanced-swapping">swapping</a> of user Roman Pekar. </p> <pre><code>EDIT: Solution based on Example1 from Tometzky Imports Npgsql Public Class Form1 Dim dServer As String = "127.0.0.1" Dim dPort As String = "5432" Dim dUser As String = "postgres" Dim dPass As String = yourpass Dim ddatabase As String = yourdatabase Private dragrect As Rectangle Private dragindex, dropindex As Integer Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim conn As New NpgsqlConnection(String.Format( _ "Server={0};Port={1};User Id={2};Password={3};Database={4};", _ dServer, dPort, dUser, dPass, ddatabase)) conn.Open() Using t As NpgsqlTransaction = conn.BeginTransaction() Using cmd As New NpgsqlCommand( _ "DROP TABLE IF EXISTS kalksad1;", conn) cmd.ExecuteNonQuery() End Using Using cmd As New NpgsqlCommand( _ "CREATE TABLE kalksad1(" &amp; _ "kalk_id int PRIMARY KEY, " &amp; _ "brkalk integer, " &amp; _ "brred integer, " &amp; _ "description text);", conn) cmd.ExecuteScalar() End Using Using cmd As New NpgsqlCommand( _ "INSERT INTO kalksad1 VALUES" &amp; _ "(12, 2, 5, 'text index 12 doc 2 row 5'), " &amp; _ "(26, 2, 1, 'text index 26 doc 2 row 1'), " &amp; _ "(30, 2, 2, 'text index 30 doc 2 row 2'), " &amp; _ "(32, 4, 1, 'text index 32 doc 4 row 1'), " &amp; _ "(36, 1, 1, 'text index 36 doc 1 row 1'), " &amp; _ "(37, 1, 2, 'text index 37 doc 1 row 2'), " &amp; _ "(38, 5, 1, 'text index 38 doc 5 row 1'), " &amp; _ "(39, 5, 2, 'text index 39 doc 5 row 2'), " &amp; _ "(42, 2, 3, 'text index 42 doc 2 row 3'), " &amp; _ "(43, 2, 4, 'text index 43 doc 2 row 4'), " &amp; _ "(46, 3, 1, 'text index 46 doc 3 row 1'), " &amp; _ "(47, 3, 2, 'text index 47 doc 3 row 2');", conn) cmd.ExecuteNonQuery() End Using t.Commit() End Using With DataGridView1 .AllowDrop = True .MultiSelect = False .Dock = DockStyle.Fill .SelectionMode = DataGridViewSelectionMode.FullRowSelect .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells .Columns.Add("col1", "ID") .Columns.Add("col2", "Doc") .Columns.Add("col3", "Row") .Columns.Add("col4", "Description") End With FillData(0) End Sub Private Sub FillData(ByVal dropindex As Integer) DataGridView1.Rows.Clear() Try Using mCon As New NpgsqlConnection(String.Format( _ "Server={0};Port={1};User Id={2};Password={3};Database={4};", _ dServer, dPort, dUser, dPass, ddatabase)) mCon.Open() Using mCmd = New NpgsqlCommand( _ "SELECT kalk_id, brkalk, brred, description " &amp; _ "FROM kalksad1 " &amp; _ "WHERE brkalk='2' ORDER BY brred", mCon) Using reader As NpgsqlDataReader = mCmd.ExecuteReader() While (reader.Read()) DataGridView1.Rows.Add(New String() _ {CStr(reader("kalk_id")), _ CStr(reader("brkalk")), _ CStr(reader("brred")), _ CStr(reader("description"))}) End While End Using End Using End Using Catch ex As Exception Debug.Print(ex.Message) End Try ''selecting a row If dropindex &lt; 0 Then dropindex = 0 With DataGridView1 .Rows(dropindex).Selected = True .CurrentCell = .Item(0, dropindex) End With End Sub #Region "dragdrop" Private Sub DataGridView1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragDrop Dim p As Point = Me.PointToClient(New Point(e.X, e.Y)) dropindex = DataGridView1.HitTest(p.X, p.Y).RowIndex If (e.Effect = DragDropEffects.Move) Then Dim dragRow As DataGridViewRow = CType(e.Data.GetData(GetType(DataGridViewRow)), DataGridViewRow) Dim _from As Integer = dragindex + 1 ''grid is zero based, document is 1 based Dim _to As Integer = dropindex + 1 Dim updown As String = "" If _from &lt; _to Then ''correction for up _to = _to + 1 updown = "!" End If '' PROCEDURE HERE ----------------------------------------------------------------- Dim affected As Integer = 0 Try Using conn As New NpgsqlConnection(String.Format( _ "Server={0};Port={1};User Id={2};Password={3};Database={4};", _ dServer, dPort, dUser, dPass, ddatabase)) conn.Open() Using t As NpgsqlTransaction = conn.BeginTransaction() Using cmd As New NpgsqlCommand( _ "UPDATE kalksad1 SET brred=_brred " &amp; _ "FROM (" &amp; _ " SELECT " &amp; _ " row_number() OVER (" &amp; _ " ORDER BY brred&lt;" &amp; _to.ToString &amp; " DESC, brred" &amp; updown &amp; "=" &amp; _from.ToString &amp; " DESC, brred&gt;=" &amp; _to.ToString &amp; " DESC, brred" &amp; _ " ) AS _brred," &amp; _ " kalk_id AS _kalk_id " &amp; _ "FROM kalksad1 " &amp; _ "WHERE brkalk=2 " &amp; _ "ORDER BY _kalk_id" &amp; _ ") AS _ " &amp; _ "WHERE kalk_id=_kalk_id AND brred!=_brred;", conn) affected = CInt(cmd.ExecuteNonQuery()) End Using If affected &gt; 0 Then t.Commit() End Using End Using Catch ex As Exception Debug.Print(ex.Message) End Try ''--------------------------------------------------------------------------------- FillData(dropindex) ''clear, fill and select dropped row End If End Sub Private Sub DataGridView1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragOver e.Effect = DragDropEffects.Move End Sub Private Sub DataGridView1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseDown dragindex = DataGridView1.HitTest(e.X, e.Y).RowIndex If dragindex &gt; -1 Then Dim dragSize As Size = SystemInformation.DragSize dragrect = New Rectangle(New Point(CInt(e.X - (dragSize.Width / 2)), CInt(e.Y - (dragSize.Height / 2))), dragSize) Else dragrect = Rectangle.Empty End If End Sub Private Sub DataGridView1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles DataGridView1.MouseMove If (e.Button And MouseButtons.Left) = MouseButtons.Left Then If (dragrect &lt;&gt; Rectangle.Empty AndAlso Not dragrect.Contains(e.X, e.Y)) Then Me.DoDragDrop(DataGridView1.Rows(dragindex), DragDropEffects.Move) End If End If End Sub #End Region End Class </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload