ฉันต้องการเปลี่ยนชื่อฐานข้อมูล แต่ได้รับข้อผิดพลาดที่ 'ไม่สามารถล็อกแบบเอกสิทธิ์เฉพาะบุคคล' ในฐานข้อมูลซึ่งแสดงว่ามีการเชื่อมต่อบางส่วนยังคงทำงานอยู่
ฉันจะฆ่าการเชื่อมต่อทั้งหมดไปยังฐานข้อมูลเพื่อให้ฉันสามารถเปลี่ยนชื่อได้อย่างไร?
ฉันต้องการเปลี่ยนชื่อฐานข้อมูล แต่ได้รับข้อผิดพลาดที่ 'ไม่สามารถล็อกแบบเอกสิทธิ์เฉพาะบุคคล' ในฐานข้อมูลซึ่งแสดงว่ามีการเชื่อมต่อบางส่วนยังคงทำงานอยู่
ฉันจะฆ่าการเชื่อมต่อทั้งหมดไปยังฐานข้อมูลเพื่อให้ฉันสามารถเปลี่ยนชื่อได้อย่างไร?
คำตอบ:
เหตุผลที่วิธีการที่อดัมแนะนำไม่ทำงานก็คือในช่วงเวลาที่คุณทำการวนรอบการเชื่อมต่อที่ใช้งานอยู่คุณสามารถสร้างการเชื่อมต่อใหม่และคุณจะพลาดสิ่งเหล่านั้น คุณสามารถใช้วิธีการต่อไปนี้แทนซึ่งไม่มีข้อเสีย:
-- set your current connection to use master otherwise you might get an error
use master
ALTER DATABASE YourDatabase SET SINGLE_USER WITH ROLLBACK IMMEDIATE
--do you stuff here
ALTER DATABASE YourDatabase SET MULTI_USER
สคริปต์เพื่อดำเนินการนี้ให้แทนที่ 'DB_NAME' ด้วยฐานข้อมูลเพื่อฆ่าการเชื่อมต่อทั้งหมดไปที่:
USE master
GO
SET NOCOUNT ON
DECLARE @DBName varchar(50)
DECLARE @spidstr varchar(8000)
DECLARE @ConnKilled smallint
SET @ConnKilled=0
SET @spidstr = ''
Set @DBName = 'DB_NAME'
IF db_id(@DBName) < 4
BEGIN
PRINT 'Connections to system databases cannot be killed'
RETURN
END
SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
IF LEN(@spidstr) > 0
BEGIN
EXEC(@spidstr)
SELECT @ConnKilled = COUNT(1)
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
END
and spid <> @@SPID
ในSELECT @sKillConnection
คำสั่งเพื่อที่จะไม่พยายามฆ่าการเชื่อมต่อปัจจุบันของฉันซึ่งจะสร้างข้อความแสดงข้อผิดพลาด
ฆ่ามันและฆ่ามันด้วยไฟ:
USE master
go
DECLARE @dbname sysname
SET @dbname = 'yourdbname'
DECLARE @spid int
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname)
WHILE @spid IS NOT NULL
BEGIN
EXECUTE ('KILL ' + @spid)
SELECT @spid = min(spid) from master.dbo.sysprocesses where dbid = db_id(@dbname) AND spid > @spid
END
การใช้ SQL Management Studio Express:
ในทรี Object Explorer เจาะลึกภายใต้การจัดการเป็น "การตรวจสอบกิจกรรม" (หากคุณไม่พบที่นั่นแล้วคลิกขวาบนเซิร์ฟเวอร์ฐานข้อมูลและเลือก "การตรวจสอบกิจกรรม") เปิดการตรวจสอบกิจกรรมคุณสามารถดูข้อมูลกระบวนการทั้งหมด คุณควรจะสามารถค้นหาล็อคสำหรับฐานข้อมูลที่คุณสนใจและฆ่าล็อคเหล่านั้นซึ่งจะฆ่าการเชื่อมต่อ
คุณควรจะสามารถเปลี่ยนชื่อได้หลังจากนั้น
ฉันเคยใช้:
ALTER DATABASE DB_NAME SET SINGLE_USER WITH ROLLBACK IMMEDIATE
GO
SP_RENAMEDB 'DB_NAME','DB_NAME_NEW'
Go
ALTER DATABASE DB_NAME_NEW SET MULTI_USER -- set back to multi user
GO
ALTER DATABASE [Test]
SET OFFLINE WITH ROLLBACK IMMEDIATE
ALTER DATABASE [Test]
SET ONLINE
ใช้ออฟไลน์ใช้เวลาสักครู่และบางครั้งฉันประสบปัญหาบางอย่างกับที่ ..
วิธีที่แข็งแกร่งที่สุดในความคิดของฉัน:
แยกออก คลิกขวาที่ DB -> Tasks -> Detach ... ตรวจสอบ "Drop Connections" ตกลง
Reattach คลิกขวาที่ฐานข้อมูล -> แนบ .. เพิ่ม ... -> เลือกฐานข้อมูลของคุณแล้วเปลี่ยนคอลัมน์แนบเป็นชื่อฐานข้อมูลที่คุณต้องการ ตกลง
Select 'Kill '+ CAST(p.spid AS VARCHAR)KillCommand into #temp
from master.dbo.sysprocesses p (nolock)
join master..sysdatabases d (nolock) on p.dbid = d.dbid
Where d.[name] = 'your db name'
Declare @query nvarchar(max)
--Select * from #temp
Select @query =STUFF((
select ' ' + KillCommand from #temp
FOR XML PATH('')),1,1,'')
Execute sp_executesql @query
Drop table #temp
ใช้ฐานข้อมูล 'ต้นแบบ' และเรียกใช้แบบสอบถามนี้จะฆ่าการเชื่อมต่อที่ใช้งานทั้งหมดจากฐานข้อมูลของคุณ
ฉันมักจะพบข้อผิดพลาดเมื่อฉันพยายามกู้คืนฐานข้อมูลฉันมักจะไปที่ด้านบนสุดของแผนภูมิใน Management Studio และคลิกขวาและรีสตาร์ทเซิร์ฟเวอร์ฐานข้อมูล (เพราะอยู่ในเครื่องพัฒนานี่อาจไม่เหมาะสำหรับการผลิต ) นี่เป็นการปิดการเชื่อมต่อฐานข้อมูลทั้งหมด
ALTER DATABASE ... SET SINGLE_USER
คำสั่งในคำตอบอื่น ๆ กลับข้อผิดพลาด 'ไม่สามารถล็อคแบบเอกสิทธิ์เฉพาะบุคคล' กลับคืนได้)
ใน MS SQL Server Management Studio บนออบเจกต์ explorer ให้คลิกขวาที่ฐานข้อมูล ในเมนูบริบทที่ตามมาให้เลือก 'Tasks -> Take ออฟไลน์'
วิธี "ฆ่าด้วยไฟ" อีกวิธีหนึ่งคือเพียงแค่เริ่มบริการ MSSQLSERVER ใหม่ ฉันชอบทำสิ่งต่าง ๆ จาก commandline การวางสิ่งนี้ลงใน CMD จะทำเช่นนั้น: NET STOP MSSQLSERVER และ NET START MSSQLSERVER
หรือเปิด "services.msc" และค้นหา "SQL Server (MSSQLSERVER)" และคลิกขวาเลือก "เริ่มต้นใหม่"
สิ่งนี้จะ "แน่นอน" ฆ่าการเชื่อมต่อทั้งหมดไปยังฐานข้อมูลทั้งหมดที่ทำงานบนอินสแตนซ์นั้น
(ฉันชอบสิ่งนี้ดีกว่าวิธีการมากมายที่เปลี่ยนแปลงและเปลี่ยนกลับการกำหนดค่าบนเซิร์ฟเวอร์ / ฐานข้อมูล)
ต่อไปนี้เป็นวิธีเชื่อถือได้ของประเภทนี้ใน MS SQL Server Management Studio 2008 (อาจใช้ได้กับรุ่นอื่นด้วย):
ตัวเลือกที่เหมาะกับฉันในสถานการณ์นี้เป็นดังนี้:
ลองสิ่งนี้:
ALTER DATABASE [DATABASE_NAME]
SET SINGLE_USER
WITH ROLLBACK IMMEDIATE
คลิกขวาที่ชื่อฐานข้อมูลคลิกที่คุณสมบัติเพื่อรับหน้าต่างคุณสมบัติเปิดแท็บตัวเลือกและเปลี่ยนคุณสมบัติ "จำกัด การเข้าถึง" จากผู้ใช้หลายคนเป็นผู้ใช้รายเดียว เมื่อคุณกดปุ่ม OK ระบบจะแจ้งให้คุณปิดการเชื่อมต่อที่เปิดอยู่ทั้งหมดเลือก "ใช่" และคุณได้รับการตั้งค่าให้เปลี่ยนชื่อฐานข้อมูล ....
สิ่งเหล่านี้ใช้ไม่ได้กับฉัน (SQL2008 Enterprise) ฉันไม่เห็นกระบวนการทำงานหรือผู้ใช้ที่เชื่อมต่อกับฐานข้อมูล การรีสตาร์ทเซิร์ฟเวอร์ (คลิกขวาบน Sql Server ใน Management Studio และเลือก Restart) อนุญาตให้ฉันกู้คืนฐานข้อมูล
ฉันใช้ SQL Server 2008 R2 ฐานข้อมูลของฉันถูกตั้งค่าไว้แล้วสำหรับผู้ใช้คนเดียวและมีการเชื่อมต่อที่ จำกัด การดำเนินการใด ๆ บนฐานข้อมูล ดังนั้นโซลูชันของ SQLMenace ที่แนะนำจึงตอบสนองด้วยข้อผิดพลาด นี่คือหนึ่งในที่ทำงานในกรณีของฉัน
ฉันใช้ sp_who เพื่อรับรายการกระบวนการทั้งหมดในฐานข้อมูล สิ่งนี้ดีกว่าเพราะคุณอาจต้องการตรวจสอบกระบวนการที่จะฆ่า
declare @proc table(
SPID bigint,
Status nvarchar(255),
Login nvarchar(255),
HostName nvarchar(255),
BlkBy nvarchar(255),
DBName nvarchar(255),
Command nvarchar(MAX),
CPUTime bigint,
DiskIO bigint,
LastBatch nvarchar(255),
ProgramName nvarchar(255),
SPID2 bigint,
REQUESTID bigint
)
insert into @proc
exec sp_who2
select *, KillCommand = concat('kill ', SPID, ';')
from @proc
ผลลัพธ์
คุณสามารถใช้คำสั่งในคอลัมน์ KillCommand เพื่อฆ่ากระบวนการที่คุณต้องการ
SPID KillCommand
26 kill 26;
27 kill 27;
28 kill 28;
คุณสามารถใช้คำสั่ง SP_Who และฆ่ากระบวนการทั้งหมดที่ใช้ฐานข้อมูลของคุณแล้วเปลี่ยนชื่อฐานข้อมูลของคุณ