مبادلة فريدة من نوعها عمود مفهرس القيم في قاعدة البيانات

StackOverflow https://stackoverflow.com/questions/644

  •  08-06-2019
  •  | 
  •  

سؤال

لدي جدول قاعدة بيانات واحدة من المجالات (غير المفتاح الأساسي) هو وجود فهرس فريد على ذلك.الآن أريد أن مبادلة القيم تحت هذا العمود صفين.كيف يمكن أن يتم ذلك ؟ اثنين الخارقة أعلم هي:

  1. حذف كل الصفوف وإعادة إدراجها.
  2. تحديث الصفوف مع بعض قيمة أخرى ومبادلة ثم تحديث القيمة الفعلية.

ولكن لا تريد أن تذهب هذه كما لا يبدو أن الحل المناسب لهذه المشكلة.يمكن لأي شخص مساعدتي ؟

هل كانت مفيدة؟

المحلول

أعتقد أن عليك أن تذهب من أجل حل 2.ليس هناك 'مبادلة' وظيفة في أي SQL البديل أعلم.

إذا كنت بحاجة إلى القيام بذلك بانتظام ، أقترح حلا 1, اعتمادا على كيفية أجزاء أخرى من البرامج تستخدم هذه البيانات.يمكن أن يكون لديك تأمين القضايا إذا كنت غير دقيق.

ولكن باختصار:لا يوجد حل آخر من تلك التي قدمت لك.

نصائح أخرى

الكلمة السحرية هي DEFERRABLE هنا:

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;

النتيجة:

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)

كذلك اندي ايرفينغ الجواب

بالنسبة لي فقد عملت (SQL Server 2005) في حالة مماثلة حيث لدي مفتاح مركب و لا تحتاج إلى تبديل الحقل الذي هو جزء من قيد فريد.

المفتاح:pID ، LNUM rec1:10, 0 rec2:10, 1 rec3:10, 2

وأنا بحاجة لمبادلة LNUM بحيث تكون النتيجة هي

المفتاح:pID ، 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))

هناك نهج آخر يعمل مع SQL Server:استخدام درجة الحرارة الجدول الانضمام إليها في عبارة UPDATE.

سبب المشكلة هو وجود صفين مع نفس القيمة في نفس الوقت, ولكن إذا قمت بتحديث كل الصفوف في وقت واحد (الجديد, فريدة من نوعها القيم) لا يوجد انتهاك القيد.

الزائفة رمز:

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

شكرا على الغنية ح لهذه التقنية.- مارك

وأعتقد أيضا أن #2 هو أفضل رهان ، على الرغم من أنني سوف تأكد من التفاف عليه في الصفقة في حالة حدوث خطأ في منتصف التحديث.

بديل (بما أنك سألت) إلى تحديث فهرس فريد القيم مع قيم مختلفة سيتم تحديث جميع القيم الأخرى في الصفوف من صف آخر.تفعل هذا يعني أنك يمكن أن تترك فهرس فريد القيم وحدها, و في النهاية, يمكنك في نهاية المطاف مع البيانات التي تريد.كن حذرا على الرغم من, في حالة أخرى الجدول مراجع هذا الجدول في الخارجية مفتاح العلاقة ، أن كل العلاقات في قاعدة البيانات لا تزال سليمة.

لدي نفس المشكلة.هنا هو بلدي النهج المقترح في كيو.في حالتي, فهرس فريد هو سلسلة القيمة وتعريف المستخدم الصريحة النظام على الصفوف.المستخدم سوف خلط الصفوف حولها في التطبيق على شبكة الإنترنت, ثم إرسال التغييرات.

أنا أخطط لإضافة "قبل" الزناد.في الزناد ، كلما بلدي فريدة من نوعها قيمة المؤشر تحديث, أنا سوف ابحث لمعرفة ما إذا كان أي صف آخر يحمل بالفعل بلدي قيمة جديدة.إذا كان الأمر كذلك, سوف يعطيهم بلادي القديمة القيمة ، وفعالية سرقة قيمة قبالة لهم.

أنا على أمل أن الإنترنت سوف تسمح لي أن أفعل هذا خلط في قبل الزناد.

أنا ما بعد الظهر وتتيح لك معرفة بلدي الأميال.

على افتراض انك تعرف PK من صفين كنت ترغب في تحديث...هذا يعمل في SQL Server لا يمكن التحدث عن منتجات أخرى.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
------------
1       b
2       a

إلى:

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

Oracle هناك خيار تأجيلها ولكن عليك أن إضافته إلى القيد.

SET CONSTRAINT emp_no_fk_par DEFERRED; 

تأجيل جميع القيود التي deferrable خلال كامل الدورة ، يمكنك استخدام يغير الدورة مجموعة من القيود=المؤجلة البيان.

المصدر

أوراكل لديه مؤجلة التحقق من سلامة الذي يحل هذا بالضبط ، ولكن لم يكن متوفرا في أي ملقم SQL أو MySQL.

في SQL Server دمج البيان يمكن تحديث الصفوف التي عادة ما كسر فريدة من نوعها مفتاح/مؤشر.(مجرد اختبار هذا لأنه كان من الغريب.)

ومع ذلك ، يجب استخدام جدول temp/متغير إمدادات دمج w/ الصفوف اللازمة.

اعتقد عادة من قيمة على الإطلاق أي مؤشر في الجدول يمكن أن يكون.عادة - من عمود القيم - فإنه من السهل حقا.على سبيل المثال قيم العمود 'موقف' (معلومات عن النظام من عدة عناصر) هو 0.

ثم يمكنك نسخ قيمة إلى متغير ، تحديثه مع قيمة B ثم قم بتعيين قيمة B من متغير.اثنين من الاستفسارات لا أعرف أفضل حل على الرغم من.

1) تبديل معرفات اسم

id    student 

1     Abbot   
2     Doris  
3     Emerson 
4     Green  
5     Jeames  

للحصول على نموذج المدخلات, المخرجات هي:

هوية الطالب

1     Doris   
2     Abbot   
3     Green   
4     Emerson 
5     Jeames  

"في حالة n عدد الصفوف كيف ستدير......"

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top