Vă mulțumim pentru susținere

Schimbați valorile coloanelor unice indexate în baza de date

Am o tabelă de baze de date și unul dintre câmpuri (nu cheia primară) are un index unic pe acesta. Acum vreau să schimb valori în această coloană pentru două rânduri. Cum s-ar putea face asta? Două hack-uri pe care le știu sunt:

  1. Ștergeți ambele rânduri și reintroduceți-le
  2. Actualizați rândurile cu o altă valoare și schimbați și apoi actualizați la valoarea reală.

Dar nu vreau să merg pentru aceste lucruri, deoarece nu par a fi soluția adecvată a problemei. Ar putea cineva să mă ajute?

0
adăugat editat
Redenumiți coloanele?
adăugat autor MatBailie

19 răspunsuri

GDAL user-friendliness is basically nonexistent, but hot damn does it ever work well. I wrote up this guide to my own georeferencing experiments a few years ago: http://mike.teczno.com/notes/flea-market-mapping.html

Este un pic depășit, dar elementele de bază sunt: ​​găsiți puncte potrivite între imaginea dvs. și o hartă de referință (aș recomanda acum http://getlatlon. com în favoarea celui de la http://gorissen.info ), utilizați gdal_translate pentru a bate un raster virtual, re practic făcută în sensul că fișierul VRT rezultat poate fi convertit în GeoTIFF sau țiglă pe care o alegeți.

I'm doing a lot with this right now, including collaborating with Tim Waters on the excellent server-side Map Warper mentioned in this thread, so there may be some new stuff in the near future loosely based on some experiments I did in JS last year: http://mike.teczno.com/notes/canvas-warp.html

22
adăugat
Michal, mulțumesc foarte mult! Am fost curios cum să găsiți locația pixelilor și menționați că ați folosit paleta de informații Photoshop, care este utilă. Cred că pot să scap de folosirea unei transformări de ordinul I. Vă mulțumim pentru toate informațiile!
adăugat autor TiTi
QGIS 1.5 tocmai a fost lansat și căutând prin changelog ( qgis.org/ en/component/content/article/108.html ) Am observat că "Includerea pluginului GDAL Raster Tools în miezul QGIS".
adăugat autor TiTi

Știu două soluții bazate pe web, care merită să aruncați o privire la:

Sunt sigur că Tim Waters și-a deschis codul, așa că, chiar dacă aceste instrumente speciale nu se potrivesc nevoilor dvs., uitându-se la sursa lor, vă pot da niște cunoștințe.

Ne pare rău, eu nu pot posta mai mult de un link extern pentru că sunt aparent mai puțin decât reputația.

10
adăugat
ar trebui să puteți adăuga mai multe linkuri acum :)
adăugat autor Greg
Interesant, m-am uitat la MapWarper din nou a doua zi. Sursa este pe GitHub: github.com/timwaters/mapwarper
adăugat autor cynicalman

Consider că georeferențiatorul lui QGis este destul de decent pentru un instrument punct și faceți clic pe el. Am scris un mic ghid - imagine georeferențială cu QGIS - care este ușor de date canadian - sursă specifică, dar trece prin toți pașii de care aveți nevoie pentru a obține o hartă arbitrară în QGis.

7
adăugat

Consider că georeferențiatorul lui QGis este destul de decent pentru un instrument punct și faceți clic pe el. Am scris un mic ghid - imagine georeferențială cu QGIS - care este ușor de date canadian - sursă specifică, dar trece prin toți pașii de care aveți nevoie pentru a obține o hartă arbitrară în QGis.

7
adăugat

De asemenea, puteți utiliza pluginul de redresare a imaginilor în MapWindow . Utilizează un algoritm îmbunătățit de 4 sau 6 puncte.

2
adăugat

De asemenea, puteți utiliza pluginul de redresare a imaginilor în MapWindow . Utilizează un algoritm îmbunătățit de 4 sau 6 puncte.

2
adăugat

Deoarece utilizați imagini aeriene: aveți nevoie de orthorectification? În acest caz, cred că ILWIS ar fi cel mai bun pariu, deși GRASS o susține, de asemenea (nu am încercat asta însumi).

Fluxul de lucru pentru ILWIS este descris aici: http://spatial-analyst.net/PDF/TN_Ortofoto_in_ILWIS.pdf

2
adăugat
Fluxul de lucru orthorectification GRASS este disponibil aici: grassbook.org -> Meniu stânga -> Capitol de probă: -> Aeriene + Ortho (PDF)
adăugat autor Dag Haavi Finstad

OpenEV vine cu FWTools, pare ok pentru mine, dar eu încărc 300 MB imagini în QGIS cu ușurință și să se ocupe cu ei acolo. Deci, o pot recomanda doar din uz casual.

http://OpenEV.sourceforge.net

Include NITF

și este construit cu GDAL

1
adăugat

Dacă aveți sau puteți crea un fișier * .geom pentru imaginea dvs., puteți utiliza orthoigen este gdal pentru quorthorectify imaginile.

1
adăugat

De asemenea, cred că # 2 este cel mai bun pariu, deși aș fi sigur că o voi împacheta într-o tranzacție în cazul în care ceva nu merge prost la mijlocul actualizării.

O alternativă (de când ați cerut) de a actualiza valorile indexului unic cu valori diferite ar fi să actualizați toate celelalte valori din rânduri la cele ale celuilalt rând. Acest lucru înseamnă că puteți lăsa singuri valorile Indexului Unic și, în cele din urmă, veți ajunge la datele pe care le doriți. Fiți atenți, totuși, în cazul în care un alt tabel se referă la acest tabel într-o relație de chei străine, că toate relațiile din DB rămân intacte.

0
adăugat

Pentru Oracle există o opțiune, DEFERRED, dar trebuie să o adăugați la constrângerea ta.

SET CONSTRAINT emp_no_fk_par DEFERRED; 

Pentru a amâna toate constrângerile care sunt amânate în timpul întregii sesiuni, puteți utiliza constrângerile ALTER SESSION SET = instrucțiunea DEFERRED.

Sursă

0
adăugat

Oracle a amânat controlul integrității care rezolvă exact acest lucru, dar nu este disponibil nici în SQL Server, nici în MySQL.

0
adăugat

În SQL Server, instrucțiunea MERGE poate actualiza rânduri care ar sparge în mod normal un KEY / INDEX UNIC. (Doar testat acest lucru pentru că eram curios.)

Cu toate acestea, va trebui să utilizați un tabel / variabilă temp pentru a furniza MERGE w / rândurile necesare.

0
adăugat

Cuvantul magic este DEFERRABIL aici:

DROP TABLE ztable CASCADE;
CREATE TABLE ztable
    ( id integer NOT NULL PRIMARY KEY
    , payload varchar
    );
INSERT INTO ztable(id,payload) VALUES (1,'one' ), (2,'two' ), (3,'three' );
SELECT * FROM ztable;


    -- This works, because there is no constraint
UPDATE ztable t1
SET payload=t2.payload
FROM ztable t2
WHERE t1.id IN (2,3)
AND t2.id IN (2,3)
AND t1.id <> t2.id
    ;
SELECT * FROM ztable;

ALTER TABLE ztable ADD CONSTRAINT OMG_WTF UNIQUE (payload)
    DEFERRABLE INITIALLY DEFERRED
    ;

    -- This should also work, because the constraint 
    -- is deferred until "commit time"
UPDATE ztable t1
SET payload=t2.payload
FROM ztable t2
WHERE t1.id IN (2,3)
AND t2.id IN (2,3)
AND t1.id <> t2.id
    ;
SELECT * FROM ztable;

REZULTAT:

DROP TABLE
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "ztable_pkey" for table "ztable"
CREATE TABLE
INSERT 0 3
 id | payload
----+---------
  1 | one
  2 | two
  3 | three
(3 rows)

UPDATE 2
 id | payload
----+---------
  1 | one
  2 | three
  3 | two
(3 rows)

NOTICE:  ALTER TABLE / ADD UNIQUE will create implicit index "omg_wtf" for table "ztable"
ALTER TABLE
UPDATE 2
 id | payload
----+---------
  1 | one
  2 | two
  3 | three
(3 rows)
0
adăugat
Aceasta funcționează în MySQL?
adăugat autor Marco Demaio
@ MarcoDemaio Nu știu. Mă tem că nu: din moment ce mysql nu permite actualizări de la auto-aderenți, aș presupune că este murdar - citește. Dar ai putea încerca ...
adăugat autor wildplasser
curat, simplu si functioneaza frumos, multumesc om :)
adăugat autor Aldos

Am aceeasi problema. Iată abordarea mea propusă în PostgreSQL. În cazul meu, indexul meu unic este o valoare de secvență, definind o comandă explicită de utilizator pe rândurile mele. Utilizatorul va amesteca rândurile în jurul unei aplicații web, apoi va trimite modificările.

Am de gând să adaug un declanșator "înainte". În acel declanșator, de fiecare dată când valoarea mea index unică este actualizată, voi căuta să văd dacă un alt rând conține deja noua mea valoare. Dacă da, îi voi da vechea lor valoare și îi voi fura efectiv valoarea.

Sper că PostgreSQL mi-ar permite să fac acest amestec în declanșarea anterioară.

Voi posta înapoi și vă voi anunța kilometrajul meu.

0
adăugat

Presupunând că știți PK a celor două rânduri pe care doriți să le actualizați ... Aceasta funcționează în SQL Server, nu poate vorbi pentru alte produse. SQL este (ar trebui să fie) atomic la nivel de declarație:

CREATE TABLE testing
(
    cola int NOT NULL,
    colb CHAR(1) NOT NULL
);

CREATE UNIQUE INDEX UIX_testing_a ON testing(colb);

INSERT INTO testing VALUES (1, 'b');
INSERT INTO testing VALUES (2, 'a');

SELECT * FROM testing;

UPDATE testing
SET colb = CASE cola WHEN 1 THEN 'a'
                WHEN 2 THEN 'b'
                END
WHERE cola IN (1,2);

SELECT * FROM testing;

astfel încât veți merge de la:

cola    colb
------------
1       b
2       a

la:

cola    colb
------------
1       a
2       b
0
adăugat
Acest lucru nu a funcționat pentru mine în MySQL.
adăugat autor activout.se

Cred că ar trebui să mergeți pentru soluția 2. Nu există nici o funcție de "swap" în varianta SQL despre care știu.

Dacă trebuie să faceți acest lucru în mod regulat, vă sugerez soluția 1, în funcție de modul în care alte părți ale software-ului folosesc aceste date. Puteți avea probleme de blocare dacă nu sunteți atent.

Dar pe scurt: nu există altă soluție decât cele pe care le-ați oferit.

0
adăugat

Există o altă abordare care funcționează cu SQL Server: utilizați o tabelă temp care se alăture acesteia în instrucțiunea UPDATE.

Problema este cauzată de faptul că aveți două rânduri cu aceeași valoare în același timp , dar dacă actualizați ambele rânduri simultan (la valorile lor noi, unice), nu există nicio încălcare a constrângerilor.

Pseudo cod:

-- setup initial data values:
insert into data_table(id, name) values(1, 'A')
insert into data_table(id, name) values(2, 'B')

-- create temp table that matches live table
select top 0 * into #tmp_data_table from data_table

-- insert records to be swapped
insert into #tmp_data_table(id, name) values(1, 'B')
insert into #tmp_data_table(id, name) values(2, 'A')

-- update both rows at once! No index violations!
update data_table set name = #tmp_data_table.name
from data_table join #tmp_data_table on (data_table.id = #tmp_data_table.id)

Mulțumită lui Rich H pentru această tehnică. - Marcă

0
adăugat
Ar putea fi un pic cam vechi, dar încercam să fac o pagină de "rearanjare" pentru aplicația mea de argint, deoarece clientul dorea să sorteze rapoartele printr-o comandă specifică - am adăugat o coloană de sortare dar, din moment ce este o cheie unică, am fost având probleme la actualizarea acestuia. Am ajuns sa folosesc o variabila de tabel, dar principiul este acelasi (nu imi plac tabelele de temp pentru a fi sincer!). Multumesc pentru ideea :)
adăugat autor Charleh

De obicei mă gândesc la o valoare pe care nici un indice din tabelul meu nu o poate avea. De obicei - pentru valorile unice ale coloanelor - este foarte ușor. De exemplu, pentru valorile poziției coloanei (informații despre ordinea mai multor elemente) este 0.

Apoi puteți copia valoarea A la o variabilă, o actualizați cu valoarea B și apoi setați valoarea B din variabila dvs. Două întrebări, dar nu știu o soluție mai bună.

0
adăugat