Swap egyedi indexelt oszlop értékeit adatbázisban

szavazat
47

Van egy adatbázis tábla és az egyik olyan terület (nem az elsődleges kulcs), amelynek egyedi index rajta. Most azt akarom, hogy a csere értékeket ebben az oszlopban a két sor. Hogyan lehet ezt megtenni? Két hack tudom, hogy:

  1. Törlés mind a sorok és helyezze be őket újra
  2. Frissítse sorok más érték, és a swap, majd frissítse a tényleges érték.

De én nem akarom, hogy az ilyen, mivel nem úgy tűnik, hogy a megfelelő megoldást a problémára. Tudna valaki segíteni?

A kérdést 03/08/2008 10:55
a forrás felhasználó
Más nyelveken...                            


12 válasz

szavazat
8

Azt hiszem, akkor menjen oldatos 2. Nincs „swap-” funkció bármilyen SQL változat tudok.

Ha kell ezt rendszeresen, azt javaslom oldat 1, attól függően, hogy más a szoftver ezeket az adatokat. Akkor olyan reteszelő kérdéseket, ha nem vigyázunk.

De röviden: nincs más megoldás, mint az ember, feltéve.

Válaszolt 03/08/2008 13:26
a forrás felhasználó

szavazat
2

Azt is gondolom, hogy a # 2 a legjobb megoldás, bár én biztos, hogy csavarja be egy ügylet, ha valami elromlik közepén frissítés.

Egy másik (mivel kérdezted) frissítése a Unique index értékek különböző értékeket lenne frissíteni az összes többi értékeket a sorok, hogy a másik sor. Ezáltal azt jelenti, hogy lehet elhagyni a Unique index értékek egyedül, és a végén, ha a végén a kívánt adatokat. Legyen óvatos, bár abban az esetben, egy másik tábla hivatkozásokat ez a táblázat egy idegen kulcs viszonyt, hogy az összes kapcsolatot a KT sértetlen marad.

Válaszolt 03/08/2008 14:22
a forrás felhasználó

szavazat
2

Feltételezve, hogy ismerjük a PK a két sor a frissíteni kívánt ... Ez működik az SQL Server, nem lehet beszélni más termékek esetében. SQL (állítólag) atomi a beszámoló szintjén:

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

CREATE UNIQUE INDEX UIX_testing_a ON testing(colb);

INSERT IGNORE  INTO testing VALUES (1, 'b');
INSERT IGNORE  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;

így fog menni:

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

nak nek:

cola    colb
------------
1       a
2       b
Válaszolt 16/09/2008 15:57
a forrás felhasználó

szavazat
5

További Andy Irving válasza

ez nekem dolgozott (az SQL Server 2005) egy hasonló helyzetben, amikor van egy összetett kulcsot, és azt kell cserélni egy olyan területen, amely része az egyedi korlát.

kulcs: plD, LNUM REC1: 10, 0 rec2: 10, 1 rec3: 10, 2

és azt kell cserélni LNUM úgy, hogy az eredmény

kulcs: plD, LNUM REC1: 10, 1 rec2: 10, 2 rec3: 10, 0

Az SQL szükséges:

UPDATE    DOCDATA    
SET       LNUM = CASE LNUM
              WHEN 0 THEN 1
              WHEN 1 THEN 2 
              WHEN 2 THEN 0 
          END
WHERE     (pID = 10) 
  AND     (LNUM IN (0, 1, 2))
Válaszolt 10/12/2008 13:19
a forrás felhasználó

szavazat
2

Ugyanaz a problémám. Itt a javasolt megközelítés PostgreSQL. Az én esetemben, az én egyedi index egy sorrend értéket, meghatároz egy felhasználó kifejezett rendű én sorokat. A felhasználó shuffle sorok körül egy web-app, majd be a változásokat.

Azt tervezem, hogy adjunk egy „előtte” ravaszt. Ebben a ravaszt, amikor én egyedi index értéke frissítik, meg fogom nézni, hogy ha bármilyen más sorban már rendelkezik az új értéket. Ha igen, adok nekik a régi érték, és hatékonyan ellopják az értéket le őket.

Remélem, hogy a PostgreSQL lehetővé teszi számomra, hogy ezt shuffle az előtt ravaszt.

Majd tegye vissza, és tudd, én futott.

Válaszolt 24/06/2009 04:58
a forrás felhasználó

szavazat
1

Oracle halasztást integritás ellenőrzést, amely megoldja pontosan, de ez nem áll rendelkezésre, vagy az SQL Server vagy MySQL.

Válaszolt 19/03/2010 20:29
a forrás felhasználó

szavazat
5

Van egy másik megközelítés, amely együttműködik a SQL Server: ezúttal egy temp tábla csatlakoznak rá a UPDATE utasítás.

A problémát az okozza, hogy két sorban azonos értékkel egyidejűleg , de ha frissíteni mindkét sort egyszerre (az új, egyedi érték), nincs megszorítás megsértése miatt.

Pszeudo-kód:

-- 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)

Hála Rich H ezt a technikát. - Mark

Válaszolt 04/04/2012 20:40
a forrás felhasználó

szavazat
1

Az SQL Server, a MERGE utasítás frissítheti sorok, amelyek általában törni egy egyedi kulcs / INDEX. (Csak tesztelték ezt, mert kíváncsi voltam.)

Azonban azt kell használni a temp tábla / változó a kínálat MERGE w / a szükséges sorokat.

Válaszolt 20/04/2012 20:12
a forrás felhasználó

szavazat
21

A varázsszó halasztható itt:

DROP TABLE ztable CASCADE;
CREATE TABLE ztable
    ( id integer NOT NULL PRIMARY KEY
    , payload varchar
    );
INSERT IGNORE  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;

EREDMÉNY:

DROP TABLE
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "ztable_pkey" for table "ztable"
CREATE TABLE
INSERT IGNORE  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)
Válaszolt 15/09/2012 13:38
a forrás felhasználó

szavazat
1

Az Oracle lehetőség van felvételről, de van, hogy add meg a korlátot.

SET CONSTRAINT emp_no_fk_par DEFERRED; 

Elhalasztására ALL korlátok, amelyek halasztható során az egész folyamatot, akkor az ALTER SESSION SET korlátok = DEFERRED nyilatkozatot.

Forrás

Válaszolt 27/04/2016 14:15
a forrás felhasználó

szavazat
0

Azt általában gondolnak az értéket, amely egyáltalán nem index az asztalomhoz volna. Általában - az egyedi oszlop értékeit - ez nagyon egyszerű. Például, az értékek az oszlop „pozíció” (tájékoztatás a sorrendben több elemből) ez 0.

Ezután másold A érték egy változó, frissítse azt B érték és a beállított érték ezután a B, hogy a változó. Két lekérdezések, tudom, nem jobb megoldás mégis.

Válaszolt 18/03/2017 18:00
a forrás felhasználó

szavazat
1

1) kapcsoló az IDS neve

id    student 

1     Abbot   
2     Doris  
3     Emerson 
4     Green  
5     Jeames  

A minta bemenet, a kimenet:

id diák

1     Doris   
2     Abbot   
3     Green   
4     Emerson 
5     Jeames  

„Ha n számú sorral hogyan fogja kezelni ......”

Válaszolt 06/11/2018 08:56
a forrás felhasználó

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more