MSSQL 关于执行sp_rename的求助

php_boy 2010-05-12 09:43:01
各位大侠,

现在项目中遇到一个问题,需要对一个表进行升级。
我们的做法是先创建一个新的表B,然后把老表A的数据migration过来。
再把老表Arename成别的的,把新表Brename回老表A的名字。

但是在rename的过程中,会有一个时间段,名字为A的表不存在。应用程序访问时,会出错,
我想问一下,有没有办法可以在这段时间内让应用程序的请求hold住, 等完成rename再继续执行。

谢谢
...全文
246 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Garnett_KG 2010-05-12
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 php_boy 的回复:]

实际上在执行把老表的数据insert 到新表的时候是不用锁的, 因为数据量太大,如果用了transaction,大概是半个小时的时间,所以很难接受。

如果 仅仅是

SQL code

Begin Transcation
go
execute sp_rename 'A', 'A_temp'
go
execute sp_rename 'B', 'A'
go
commit



这……
[/Quote]

会。

php_boy 2010-05-12
  • 打赏
  • 举报
回复
实际上在执行把老表的数据insert 到新表的时候是不用锁的, 因为数据量太大,如果用了transaction,大概是半个小时的时间,所以很难接受。

如果 仅仅是 


Begin Transcation
go
execute sp_rename 'A', 'A_temp'
go
execute sp_rename 'B', 'A'
go
commit


这样其他的应用程序在insert或者select请求会被 hold住 吗?
永生天地 2010-05-12
  • 打赏
  • 举报
回复
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_a1
(
name varchar(10) NOT NULL,
A_c1 int NULL,
dt AS getdate()
) ON [PRIMARY]
GO
IF EXISTS(SELECT * FROM dbo.a1)
EXEC('INSERT INTO dbo.Tmp_a1 (name, A_c1)
SELECT name, A_c1 FROM dbo.a1 WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.a1
GO
EXECUTE sp_rename N'dbo.Tmp_a1', N'a1', 'OBJECT'
GO
COMMIT
Garnett_KG 2010-05-12
  • 打赏
  • 举报
回复
再把老表Arename成别的的,把新表Brename回老表A的名字。

》》》

这个过程要包成一个transaction.

这样便会使应用程序会挂住(申请Sch-S锁不到).
php_boy 2010-05-12
  • 打赏
  • 举报
回复
我们的表的数据记录量在千万数据级上, 而且对SLA有要求,所以不能有访问出错的情况。
所以看有没有办法在rename的时候, 保持请求的hold状态,等完成 rename 再执行 请求。

谢谢
SQL77 2010-05-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 htl258 的回复:]
执行rename的动作太快了,没必要做的那么尴尬
[/Quote]
同意
php_boy 2010-05-12
  • 打赏
  • 举报
回复
在什么地方加判断呢,
我们做这个升级对应用程序是透明的, 而且应用程序分布在几十台机器上,

所以很难在每个应用上加上这个语句 。

有没有办法是数据库层的hold技术, 
谢谢
htl258_Tony 2010-05-12
  • 打赏
  • 举报
回复
执行rename的动作太快了,没必要做的那么尴尬
SQL_Server_Central 2010-05-12
  • 打赏
  • 举报
回复
create table a(id int)
select * into b from a
exec sp_rename 'a','c'
exec sp_rename 'b','a'
东那个升 2010-05-12
  • 打赏
  • 举报
回复
rename很快的啊。。。瞬间
noteasytoregister 2010-05-12
  • 打赏
  • 举报
回复
--加上判断
if object_id('A') is not null
dba2005 2010-05-12
  • 打赏
  • 举报
回复
只有把所有对该表的链接清除,才能改表吧,所以要先清除链接,再改表的名字。
mujian1986 2010-05-12
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 php_boy 的回复:]

实际上在执行把老表的数据insert 到新表的时候是不用锁的, 因为数据量太大,如果用了transaction,大概是半个小时的时间,所以很难接受。

如果 仅仅是

SQL code

Begin Transcation
go
execute sp_rename 'A', 'A_temp'
go
execute sp_rename 'B', 'A'
go
commit



这……
[/Quote]
楼主,你的思路好像有问题啊,为什么把insert放在tran中啊

改下3L的回复

create table a(id int)
select * into b from a
bein tran
begin try
exec sp_rename 'a','a_temp';
exec sp_rename 'b',a';
commit tran
end try
begin catch
rollback tran
end catch

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧