it-swarm.asia

كيف يمكنني تغيير مفتاح أساسي موجود في SQL Azure؟

أريد تعديل مفتاح أساسي موجود على جدول SQL Azure.
يحتوي حاليًا على عمود واحد ، وأريد إضافة عمود آخر.

الآن ، في SQL Server 2008 ، كانت هذه قطعة من الكعكة ، فقط فعلت ذلك في SSMS ، لوطي. منجز. هذه هي الطريقة التي يبدو بها PK إذا قمت ببرمجته من SQL Server:

ALTER TABLE [dbo].[Friend] ADD  CONSTRAINT [PK_Friend] PRIMARY KEY CLUSTERED 
(
  [UserId] ASC,
  [Id] ASC
)

ومع ذلك ، في SQL Azure ، عندما أحاول تنفيذ ما سبق ، سيفشل بالطبع:

Table 'Friend' already has a primary key defined on it.

حسنًا ، أحاول إسقاط المفتاح:

Tables without a clustered index are not supported in this version of SQL Server. Please create a clustered index and try again.

حسنًا ، أنا أحاول إنشاء فهرس مجمع مؤقت لإسقاط PK:

CREATE CLUSTERED INDEX IX_Test ON [Friend] ([UserId],[Id])

مما يؤدي إلى: Cannot create more than one clustered index on table 'Friend'. Drop the existing clustered index 'PK_Friend' before creating another.

عظيم ، لحظة 22.

كيف أقوم بإضافة عمود UserId إلى PK الحالي الخاص بي؟

25
Magnus

ملاحظة: اعتبارًا من الإصدار 12 من قاعدة بيانات Azure SQL ، لم تعد هذه القيود سارية.

لا يوجد شيء مثل "المؤشر الأساسي". يوجد شيء مثل "المفتاح الأساسي" وأيضًا يوجد شيء مثل "المؤشر المجمع". مفاهيم مميزة ، غالبًا ما تكون مشوشة. مع أخذ هذا التمييز في الاعتبار ، دعنا نعيد النظر في السؤال:

س 1) هل يمكن تعديل الفهرس العنقودي في جدول SQL Azure؟
ج: نعم. استخدم WITH (DROP_EXISTING=ON):

create table Friend (
    UserId int not null,
    Id int not null);
go  
create clustered index cdxFriend on Friend (UserId, Id);
go
create clustered index cdxFriend on Friend (Id, UserId) with (drop_existing=on);
go

س 2) هل يمكن تعديل الفهرس المجمّع لجدول يحتوي على قيد رئيسي أساسي؟
ج: نعم ، مثلما ورد أعلاه ، طالما لم يتم فرض قيود المفتاح الأساسي عبر الفهرس المجمع:

create table Friend (
    UserId int not null,
    Id int not null identity(1,1),
    constraint pk_Friend primary key nonclustered (Id));
create clustered index cdxFriend on Friend (UserId, Id);
go
create clustered index cdxFriend on Friend (Id, UserId) with (drop_existing=on);
go

س 3) هل يمكن تعديل قيد المفتاح الأساسي للجدول؟
ج: نعم ، طالما لم يتم فرض القيد الأساسي عبر الفهرس المجمع:

create table Friend (
    UserId int not null,
    Id int not null identity(1,1),
    constraint pk_Friend primary key nonclustered (Id));
go
create clustered index cdxFriend on Friend (UserId, Id);
go
alter table Friend drop constraint pk_Friend;
alter table Friend add constraint pk_Friend primary key nonclustered (UserId)
go

س 4) هل يمكن تعديل المفتاح الأساسي للجدول عندما يتم تنفيذه عبر الفهرس المجمع؟
ج: نعم ، إذا لم يكن للجدول أي صفوف:

create table Friend (
    UserId int not null,
    Id int not null identity(1,1),
    constraint pk_Friend primary key clustered (UserId, Id));
go
alter table Friend drop constraint pk_Friend;
alter table Friend add constraint pk_Friend primary key clustered (Id, UserId)
go

س 5) هل يمكن تعديل المفتاح الأساسي للجدول عندما يتم تنفيذه عبر الفهرس المجمع إذا كان الجدول مملوءًا؟
ج: لا. سيتم حظر أي عملية تحول فهرس مجمع مجمع إلى كومة في SQL Azure ، حتى إذا كان الجدول فارغًا :

create table Friend (
    UserId int not null,
    Id int not null identity(1,1),
    constraint pk_Friend primary key clustered (UserId, Id));
go
insert into Friend (UserId) values (1);
delete from Friend;
go
alter table Friend drop constraint pk_Friend;

كملاحظة جانبية: يمكن تعديل القيد إذا كان الجدول مبتوراً .

الحل لتغيير قيد PK لجدول مأهول هو أن تفعل الخير القديم sp_rename خدعة:

create table Friend (
    UserId int not null,
    Id int not null identity(1,1),
    constraint pk_Friend primary key clustered (UserId, Id));
go
insert into Friend (UserId) values (1);
go

create table FriendNew (
    UserId int not null,
    Id int not null identity(1,1),
    constraint pk_Friend_New primary key clustered (Id, UserId));
go

set identity_insert FriendNew on;
insert into FriendNew (UserId, Id) 
select UserId, Id
from Friend;
set identity_insert FriendNew off;
go

begin transaction
exec sp_rename 'Friend', 'FriendOld';
exec sp_rename 'FriendNew', 'Friend';
commit;
go

sp_help 'Friend';

ال sp_rename النهج يحتوي على بعض المشاكل ، والأهم من ذلك أن الأذونات على الجدول لا تنتقل أثناء إعادة التسمية ، بالإضافة إلى قيود المفتاح الخارجي.

34
Remus Rusanu