PostgreSQL, Troca de dados de determinada coluna em duas linhas
Eu tenho função complexa para trocar dados da mesma coluna de nome em linhas diferentes. Eu leio os dados primeiro, armazeno em variáveis temporárias locais, leio dados da segunda linha e se certas condições são atendidas (min / max), salve na primeira linha e depois salve as variáveis temporárias na segunda linha o que é lento e propenso a erros .
Então pensei que talvez o mesmo resultado pudesse ser alcançado apenas com o SQL.
Aqui estão os dados da amostra:
CREATE TEMP TABLE tbl(
id int PRIMARY KEY,
doc_num integer,
doc_text text
);
INSERT INTO tbl VALUES
(1, 1, 'First column text1'),
(2, 2, 'First column text2'),
(4, 3, 'First column text3'),
(7, 4, 'First column text4');
Piont é trocar apenas os dados da coluna 'doc_num' na direção desejada, que pode ser para cima ou para baixo, o que eu faço com funções separadas.
Se eu posso escrever uma consulta simples em inglês que soará assim:
Primeira consulta:
SWAP DOC_NUM in row 2 with DOC_NUM in row 3 IF DOC_NUM in row 3 IS <= MAX(DOC_NUM);
Segunda consulta:
SWAP DOC_NUM in row 3 with DOC_NUM in row 2 IF DOC_NUM in row 2 IS >= MIN(DOC_NUM);
Essas consultas são possíveis para escrever com o PostgreSQL e como?
Aqui está o código real (que é feio) de um programa real que "faz um trabalho" e precisa de melhorias.
Private Sub DataGridView2_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView2.KeyDown
'SWAP --------------------------------------
If e.Control And e.KeyCode = Keys.Left Then
Debug.Print("Swap left/down")
Dim target_nrow As Integer
Dim target_index As Integer
Dim selected_nrow As Integer
Dim selected_index As Integer
Dim target_row As Integer = selected_row - 1
Using conn As New NpgsqlConnection(String.Format("Server={0};Port={1};User Id={2};Password={3};Database={4};", dbServer, dbPort, dbUser, dbPass, mydatabase))
conn.Open()
Dim t As NpgsqlTransaction = conn.BeginTransaction()
Using cmd As New NpgsqlCommand( _
"SELECT cur_id, doc_num, nrow " & _
"FROM " & mytable & " " & _
"WHERE doc_num='" & active_doc.ToString & "' AND nrow='" & selected_row.ToString & "'", conn)
Using dr As NpgsqlDataReader = cmd.ExecuteReader()
While dr.Read()
selected_index = CInt(dr(0))
selected_nrow = CInt(dr(2))
End While
End Using
End Using
Using cmd As New NpgsqlCommand( _
"SELECT cur_id, doc_num, nrow " & _
"FROM " & mytable & " " & _
"WHERE doc_num='" & active_doc.ToString & "' AND nrow='" & target_row.ToString & "'", conn)
Using dr As NpgsqlDataReader = cmd.ExecuteReader()
While dr.Read()
target_index = CInt(dr(0))
target_nrow = CInt(dr(2))
End While
End Using
End Using
Dim updated_t As Integer = 0
Using cmd As New NpgsqlCommand( _
"UPDATE " & mytable & " SET " & _
"nrow=" & selected_nrow & " " & _
"WHERE cur_id=" & target_index.ToString, conn)
updated_t = CInt(cmd.ExecuteNonQuery())
cmd.Dispose()
End Using
Dim updated_s As Integer = 0
Using cmd As New NpgsqlCommand( _
"UPDATE " & mytable & " SET " & _
"nrow=" & target_nrow & " " & _
"WHERE cur_id=" & selected_index.ToString, conn)
updated_s = CInt(cmd.ExecuteNonQuery())
cmd.Dispose()
End Using
If updated_s > 0 And updated_t > 0 Then
t.Commit()
Else
t.Rollback()
End If
t.Dispose()
conn.Close()
conn.Dispose()
End Using
Refreshlist(active_doc)
End If
If e.Control And e.KeyCode = Keys.Right Then
Debug.Print("Swap right/up")
'similar code to swap up again
End If
Toda a história está em questão sobre como tornar isso mais curto, mais rápido e mais elegante?