【发布时间】:2011-01-23 19:16:41
【问题描述】:
我有一些这样的代码,用于将数据文件批量插入到表中,其中数据文件和表名是变量:
DECLARE @sql AS NVARCHAR(1000)
SET @sql = 'BULK INSERT ' + @tableName + ' FROM ''' + @filename + ''' WITH (CODEPAGE=''ACP'', FIELDTERMINATOR=''|'')'
EXEC (@sql)
标准表的工作正常,但现在我需要做同样的事情来将数据加载到 临时 表中(例如,#MyTable)。但是当我尝试这个时,我得到了错误:
Invalid Object Name: #MyTable
我认为问题在于BULK INSERT 语句是即时构造的,然后使用EXEC 执行,而#MyTable 在EXEC 调用的上下文中不可访问。
我需要像这样构造BULK INSERT 语句的原因是我需要将文件名插入到语句中,而这似乎是唯一的方法。所以,我似乎可以或者有一个变量文件名,或者使用一个临时表,但不能同时使用。
还有其他方法可以实现这一点 - 或许是使用OPENROWSET(BULK...)?
更新: 好的,所以我听到的是 BULK INSERT 和临时表对我不起作用。感谢您的建议,但在我的情况下,将我的更多代码移动到动态 SQL 部分是不切实际的。
尝试过OPENROWSET(BULK...),似乎遇到了同样的问题,即它无法处理变量文件名,我需要像以前一样动态构造 SQL 语句(因此无法访问临时表)。
所以,这让我只有一个选择,即使用非临时表并以不同的方式实现进程隔离(通过确保任何时候只有一个进程可以使用这些表 - 我能想到几种方法来做到这一点)。
这很烦人。按照我原本打算的方式来做会方便得多。只是其中一件应该是微不足道的事情,但最终会浪费你一整天的时间......
【问题讨论】:
-
您是否尝试过将静态批量插入临时表?
-
@Andrey:老实说我没有,但我现在有了 - 它按我的预期工作。
-
我知道这已经解决了,但只是提一下:您可以编写一个 SQLCLR 存储过程来接收任何这些参数(例如文件名)并吐出结果。此时您只需创建临时表,然后创建
INSERT INTO #mytemp EXEC SQLCLRproc @filename='path.txt';。 SQL# 库(我创建的)中已经存在这样的过程。该过程称为File_SplitIntoFields,并允许指定字段名称和数据类型(虽然不确定CODEPAGE='ACP')。我应该提到它在免费版本中不是,但它使这变得非常容易。
标签: sql sql-server tsql bulkinsert