ฉันจะเปลี่ยนคีย์หลักที่มีอยู่ใน SQL Azure ได้อย่างไร


25

ฉันต้องการแก้ไขคีย์หลักที่มีอยู่ในตาราง 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 ที่มีอยู่ได้อย่างไร


ที่เกี่ยวข้อง: stackoverflow.com/questions/5645145/…
Nick Chammas

คำตอบ:


34

หมายเหตุ: ตั้งแต่ Azure SQL Database v12 ข้อ จำกัด เหล่านี้ใช้ไม่ได้อีกต่อไป

ไม่มีสิ่งนั้นเป็น 'ดัชนีหลัก' มีสิ่งนั้นเป็น 'คีย์หลัก' และยังมีสิ่งนั้นเป็น 'ดัชนีคลัสเตอร์' แนวคิดที่แตกต่างมักสับสน ด้วยความแตกต่างในใจให้ลองทบทวนคำถาม

Q1) สามารถปรับเปลี่ยนดัชนีคลัสเตอร์ในตาราง 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

Q2) ดัชนีคลัสเตอร์ของตารางที่มีข้อ จำกัด คีย์หลักสามารถแก้ไขได้หรือไม่?
ตอบ: ใช่เหมือนข้างบนตราบใดที่ไม่ได้บังคับใช้ข้อ จำกัด คีย์หลักผ่านดัชนีคลัสเตอร์:

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

Q3) สามารถแก้ไขข้อ จำกัด คีย์หลักของตารางได้หรือไม่?
ตอบ: ใช่ตราบใดที่ข้อ จำกัด หลักไม่ถูกบังคับใช้ผ่านดัชนีคลัสเตอร์:

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

Q4) สามารถปรับเปลี่ยนคีย์หลักของตารางได้เมื่อมีการบังคับใช้ผ่านดัชนีคลัสเตอร์หรือไม่
ตอบ: ใช่ถ้าตารางไม่เคยมีแถว:

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

Q5) สามารถปรับเปลี่ยนคีย์หลักของตารางได้เมื่อมีการบังคับใช้ผ่านดัชนีคลัสเตอร์หรือไม่หากมีการเติมข้อมูลในตาราง
ตอบ: ไม่การดำเนินการใด ๆ ที่แปลงดัชนีคลัสเตอร์ที่มีประชากรเป็นฮีปจะถูกบล็อกใน 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วิธีมีบางประเด็นที่สำคัญที่สุดคือการที่สิทธิ์บนโต๊ะไม่ได้ดำเนินการในระหว่างการเปลี่ยนชื่อเช่นเดียวกับข้อ จำกัด ที่สำคัญต่างประเทศ


A1-A4 นั้นไม่มีคำตอบในกรณีของฉัน A5 ทำเคล็ดลับได้แม้ว่ารหัสของฉันไม่ใช่คอลัมน์ข้อมูลประจำตัว
แมกนัส

วิธีแก้ปัญหา sp_rename มีประโยชน์!
Justin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.