我想维护一个使用ADO方法通过Excel将数据上传到SQL Server的系统。该过程包括两个步骤:
dbo.TableTemp
dbo.GoodTable
delete from dbo.TableTemp
有没有办法确定两个用户的活动不重叠?例如,在user2插入数据之后和处理数据之前,不会执行user1的delete from dbo.TableTemp
?
更新。不幸的是,我没有成功使用#temp
个表格。它们似乎过于临时,当我尝试向其中插入数据时#temps已经不存在了。对于上传数据,我使用Sergey Vaselenko从这里下载的代码变体:http://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm#Excel Data Export to SQL Server using ADO
在Sergey的解决方案中,可以在步骤1中插入数据之前通过存储过程创建表。但是当我用存储过程创建#temp
表时,它会在程序结束时消失,所以我不能向其插入数据。有什么帮助吗?
答案 0 :(得分:4)
使用temporary tables #TableTemp
。这些特定于每个会话,因此不会重叠。
临时表有两种类型:本地和全局。他们不同 彼此之间的名字,他们的知名度和他们的 可用性。本地临时表具有单个数字符号(#) 他们名字的第一个字;它们只对于它们是可见的 用户的当前连接,并在用户删除它们 断开与SQL Server实例的连接。全球临时表 有两个数字符号(##)作为他们名字的第一个字符; 创建后,任何用户都可以看到它们 引用该表的所有用户从中断开时删除 SQL Server的实例。
更新。看起来这个特定的Excel-SQL Server Import-Export using VBA使用单独的函数来创建表,并在每次打开和关闭自己的连接时上传数据。从SQL Server的角度来看,这些函数在不同的会话中运行,因此临时表不会持久存在。我认为可以重写此解决方案以使用单个连接来创建临时表,填充,处理数据并将结果输出到永久表中。
您可能还会发现这个问题很有用:How do I make an ADODB.Connection Persistent in VBA in Excel?特别是 - Kevin Pope 的回答建议使用全局连接变量打开和关闭工作簿本身:
Global dbConnPublic As ADODB.Connection
在“ThisWorkbook”对象中:
Private Sub Workbook_Open() Set dbConnPublic = openDBConn() 'Or whatever your DB connection function is called End Sub Private Sub Workbook_BeforeClose(Cancel As Boolean) dbConnPublic.Close End Sub
答案 1 :(得分:2)
另一种方法 - 使用TABLE
变量。 From MSDN
CREATE @AddedValues TABLE (ID INT, SomeValue VARCHAR(50))
然后将其正常用作查询中的表。
INSERT INTO @AddedValues (ID, SomeValue) VALUES (1, 'Test');
SELECT ID FROM @AddedValues WHERE SomeValue = 'Test';
表变量的范围仅限于批次。因此,您可以确保其他用户甚至同一用户不会从另一个批次访问它。
来自MSDN
表变量的行为类似于局部变量。它有一个明确的定义 范围。这是函数,存储过程或批处理 声明在。
答案 2 :(得分:1)
您可以将它放在临时数据库中,而不是在用户数据库中使用临时表。使用#在CREATE TABLE语句中添加tablename以在tempdb中创建它。
例如
CREATE TABLE #TableTemp (....)
只有创建临时表的会话才能访问它,SQL Server会自动删除该表。