我希望以最佳方式交换表格。
我有一个IpToCountry表,我根据我导入的外部CSV文件每周创建一个新表。

我发现进行切换的最快方法是执行以下操作:

sp_rename IpToCountry IpToCountryOld
go
sp_rename IpToCountryNew IpToCountry
go

这样做的问题是仍然可以在两者之间访问该表 如何在SQL中解决此问题?
考虑使用sp_getapplock和sp_releaseapplock,但我希望尽快保持对表函数的读取。

有帮助吗?

解决方案

假设您无法更新/插入现有表,为什么不使用 view

例如,您最初可能将数据存储在名为 IpToCountry20090303 的表中,您的视图将是这样的:

CREATE VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090303

当新数据进入时,您可以创建并填充 IpToCountry20090310 表。填充表后,只需更新您的视图:

ALTER VIEW IpToCountry
AS
SELECT * FROM IpToCountry20090310

交换机将完全是原子的,无需任何显式锁定或事务。视图更新后,您只需删除旧表(或者如果您愿意,可以保留它)。

其他提示

实现您希望实现的目标的另一种方法是使用表分区,这是SQL Server企业版中提供的一种技术。

表名可以保持不变。表导入完成后,只需切换出包含旧数据的分区,然后切换到新分区。

以下白皮书包含您开始使用所需的所有信息。

http://msdn.microsoft.com/en-us/library /ms345146.aspx

干杯,约翰

我在分区功能大规模工作时遇到了问题。 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

IpToCountryOld会发生什么?你扔掉了吗?在这种情况下,为什么不截断IpToCountry并导入我的新数据。

如果您需要保留数据,那么如何将加载日期存储在桌面上并存储“当前”数据。加载日期在WHERE子句中使用的某个地方?然后在成功加载数据时切换当前日期。

你没有说你正在使用哪个数据库,所以我不知道它有多少使用,但你有没有引用该表的存储过程?请注意,在某些平台上,SP使用对表不会随重命名而更改的表的内部引用进行编译,因此存在SP在没有重新编译的情况下不会获取新数据的风险。视图和存储的已解析查询也是如此。

在下班时间你不能导入到一张桌子吗?

或者为什么不进行数据更新,即更新现有记录并在循环导入数据时逐个记录地添加任何新记录。这将允许表保持活动并减少添加和删除完整表的总体影响。

导入数据的结构,表格设计,格式,PK等是什么?从那以后我们可以给你一个更好的答案。

刚遇到一个类似的问题,正在使用适当的锁定进行扩展问题的临时表。

您的表被引用的任何地方都可以调用存储过程来询问表名。

存储过程可以选择创建新表或根据提供的参数返回旧表。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top