от
У меня есть таблицы базы данных, и одно из полей (не первичный ключ) имеет уникальный индекс по нему. Теперь я хочу поменять значения в этом столбце на две строки. Как это можно сделать? Два таксиста, которых я знаю: Удалить обе строки и вставляете их. Обновление строк с другим значением и поменять и потом обновить до фактического значения. Но я не хочу идти для таких, как они, кажется, не быть приемлемым решением проблемы. Может кто поможет мне?

Ваш ответ

Отображаемое имя (по желанию):
Конфиденциальность: Ваш электронный адрес будет использоваться только для отправки уведомлений.

13 Ответы

0 голосов
от
У меня есть таблицы базы данных, и одно из полей (не первичный ключ) имеет уникальный индекс по нему. Теперь я хочу поменять значения в этом столбце на две строки. Как это можно сделать? Два таксиста, которых я знаю: Удалить обе строки и вставляете их. Обновление строк с другим значением и поменять и потом обновить до фактического значения. Но я не хочу идти для таких, как они, кажется, не быть приемлемым решением проблемы. Может кто поможет мне?
0 голосов
от
Я думаю, вы должны пойти на решение 2. Нет функция 'своп' в любой SQL вариант я знаю. Если вам нужно делать это регулярно, я предлагаю решение 1, в зависимости от того, как другие части программного обеспечения, используя эти данные. Вы можете иметь блокировку, если вы не будете осторожны. Но короче: нет никакого другого решения, кроме тех, которые вы предоставили.
0 голосов
от
Волшебное слово-это отложенный здесь:
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;


    

Результат:

DROP TABLE
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "ztable_pkey" for table "ztable"
CREATE TABLE
INSERT 0 3
 id | payload
0 голосов
от
Далее Энди ответил Ирвинг это работало для меня (на SQL сервере 2005) в аналогичной ситуации где у меня есть составной ключ и мне нужно поменять поля, которое является частью уникального ограничения. ключ: пид, LNUM rec1: 10, 0 rec2: 10, 1 rec3: 10, 2 и мне нужно поменять LNUM так, что результат ключ: пид, LNUM rec1: 10, 1 rec2: 10, 2 rec3: 10, 0 для SQL нужно:
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))
0 голосов
от
Есть и другой подход, который работает с SQL сервером: использовать временную таблицу, чтобы присоединиться к ней в инструкции Update. Проблема возникает при наличии двух строк с одинаковым значением в то же время, но если вы обновите обе строки сразу (в свои новые, уникальные значения), нет нарушения ограничения. Псевдо-код:


Благодаря богатому ч на эту технику.
- Марк
0 голосов
от
Я тоже думаю, что #2-это лучший выбор, хотя я бы обязательно обернуть это в транзакции, если что-то пойдет не так во время обновления. Альтернатива (раз вы спросили) обновление уникальных значений индекса с разными значениями будет обновлять все остальные значения в строках с другой строки. Делает это означает, что вы могли бы оставить уникальные значения Индекса в одиночку, и в конце концов, вы в конечном итоге с теми данными, которые вы хотите. Будьте осторожны, хотя, в случае если некоторая другая таблица ссылается на эту таблицу в связь по внешнему ключу, что все отношения в БД остаются нетронутыми.
0 голосов
от
Если вы знаете ПК из двух строк, которые требуется обновить... это работает в SQL сервере, не могу говорить за другие продукты. SQL-это (должно быть) атомов на уровне оператора:
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;
так вы будете идти от:
cola    colb


к:

cola    colb
0 голосов
от
У меня такая же проблема. Вот мой подход, предложенный в PostgreSQL. В моем случае, Мой уникальный индекс-это последовательность значений, определяющих явный пользователем заказа на мои строки. Пользователю будут тасовать строки в веб-приложение, а затем отправить изменения. Я планирую добавить "до" триггера. В тот курок, когда мое уникальное значение индекса обновляется, я буду смотреть, чтобы увидеть, если любой другой строке уже держит меня новое значение. Если да, я дам им свое старое значение, и эффективно крадут ценность от них. Я надеюсь, что PostgreSQL будет позвольте мне сделать это перемешать до триггера. Я отправлю обратно и пусть вы знаете, мой пробег.
0 голосов
от
Для Oracle есть возможность, отложить, но вы должны добавить его в свой ограничение.
SET CONSTRAINT emp_no_fk_par DEFERRED; 
Отложить все ограничения, отложенный в течение всего сеанса, вы можете использовать альтер сессии установить ограничения=отложенным заявлением. Источник
0 голосов
от
Я обычно думаю, что значение, которое абсолютно не показатель в моем столе могла. Обычно - для уникальных значений столбца - это очень легко. Например, для значений столбца '' (информация о заказе нескольких элементов) это 0. Затем вы можете скопировать значение переменной, обновить его со значением B, а затем установить значение из переменной. Два запроса, я не лучшее решение, хотя знаю.
...