我想以最佳方式交换表格 我有一个IpToCountry表,我根据我导入的外部CSV文件每周创建一个新表。
我发现进行切换的最快方法是执行以下操作:
sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go
这个问题是桌子之间仍然可以访问 如何在SQL中解决此问题? 考虑使用sp_getapplock和sp_releaseapplock,但我希望尽快保持对表函数的读取。
答案 0 :(得分:16)
假设您无法更新/插入现有表格,为什么不使用view包装对表格的所有访问权限?
例如,您最初可能将数据存储在名为 IpToCountry20090303 的表中,您的视图将是这样的:
CREATE VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090303
当新数据进入时,您可以创建并填充 IpToCountry20090310 表。填充表后,只需更新您的视图:
ALTER VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090310
交换机将完全是原子的,无需任何显式锁定或事务。视图更新后,您只需删除旧表(或者如果您愿意,可以保留它)。
答案 1 :(得分:1)
实现您希望实现的目标的另一种方法是使用表分区,这是SQL Server企业版中提供的一种技术。
表名可以保持不变。表导入完成后,只需切换出包含旧数据的分区,然后切换到新分区。
以下白皮书包含您开始使用所需的所有信息。
http://msdn.microsoft.com/en-us/library/ms345146.aspx
干杯,约翰
答案 2 :(得分:1)
我在分区功能大规模工作时遇到了问题。 CREATE和DROP PARTITION是阻塞操作,你几乎无法控制阻塞,如果它无法获得锁定,它将以严重级别16失败并终止你的连接 - 你不能陷阱并重新尝试而不重新建立连接。但它可能适合你。此外,MSS企业版是必需的,您不能使用SE - 可能对于一些较小或更具成本关注的商店来说太多了。
我还发现视图redef在sys表和对象上以高规模(=事务量+不断插入的数据的大量数量,在我的情况下)阻塞,因此这些操作可能会在重新索引和DTCC - 在一种情况下,特别是SSMS(所有事物)中的用户试图在对象资源管理器中浏览视图(有人需要告诉那些人有关READPAST)。同样,您的里程可能会有所不同。
相比之下,sp_rename对我来说效果很好:它可以控制锁定及其范围。要解决交换之前的阻塞问题,请尝试如下所示。从表面看,这似乎在高容量时具有相同的规模问题......但我在实践中没有看到它。所以,对我有用......但同样,每个人的需求和经历都是不同的。
DECLARE @dummylock bit
BEGIN TRANSACTION
BEGIN TRY
-- necessary to obtain exclusive lock on the table prior to swapping
SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM A WITH (TABLOCKX))
-- may or may not be necessary in your case
SELECT @dummylock = 1 WHERE EXISTS (SELECT 1 FROM B WITH (TABLOCKX))
exec sp_rename 'A', 'TEMP'
exec sp_rename 'B', 'A'
exec sp_rename 'TEMP', 'B'
COMMIT TRANSACTION
END TRY
BEGIN CATCH
-- other error handling here if needed
ROLLBACK TRANSACTION
END CATCH
答案 3 :(得分:0)
IpToCountryOld会发生什么?你扔掉了吗?在这种情况下,为什么不截断IpToCountry并导入我的新数据。
如果您需要保留数据,那么如何将加载日期存储在表中并将“当前”加载日期存储在WHERE子句中的某个位置?然后在成功加载数据时切换当前日期。
你没有说你正在使用哪个数据库,所以我不知道它有多少使用,但你有没有引用该表的存储过程?请注意,在某些平台上,SP使用对表不会随重命名而更改的表的内部引用进行编译,因此存在SP在没有重新编译的情况下不会获取新数据的风险。视图和存储的已解析查询也是如此。
答案 4 :(得分:0)
在下班时间你不能导入到一张桌子吗?
或者为什么不进行数据更新,即更新现有记录并在循环导入数据时逐个记录地添加任何新记录。这将允许表保持活动并减少添加和删除完整表的总体影响。
导入数据的结构,表格设计,格式,PK等是什么?从那以后我们可以给你一个更好的答案。
答案 5 :(得分:0)
刚遇到一个类似的问题,正在使用适当的锁定进行扩展问题的临时表。
您的表被引用的任何地方都可以调用存储过程来询问表名。
存储过程可以选择创建新表或根据提供的参数返回旧表。