我有一些类似的代码,用于将数据文件批量插入表中,其中数据文件和表名是变量:
DECLARE @sql AS NVARCHAR(1000) SET @sql = 'BULK INSERT ' + @tableName + ' FROM ''' + @filename + ''' WITH (CODEPAGE=''ACP'', FIELDTERMINATOR=''|'')' EXEC (@sql)
对于标准表来说,它的工作正常,但是现在我需要做同样的事情才能将数据加载到 临时 表中(例如#MyTable)。但是当我尝试这个时,我得到了错误:
#MyTable
Invalid Object Name: #MyTable
我认为问题是由于以下事实造成的:该BULK INSERT语句是动态构造的,然后使用来执行EXEC,并且#MyTable在EXEC调用上下文中是不可访问的。
BULK INSERT
EXEC
之所以需要构造这样的BULK INSERT语句,是因为我需要在该语句中插入文件名,这似乎是唯一的方法。因此,似乎我 既 可以使用变量文件名, 也可以 使用临时表,但不能同时使用两者。
是否有另一种方法可以实现这一目标-也许通过使用OPENROWSET(BULK...)?
OPENROWSET(BULK...)
更新: 好的,所以我听到的是,批量插入和临时表对我不起作用。感谢您的建议,但就我而言,将我的更多代码移入动态SQL部分并不实际。
经过尝试OPENROWSET(BULK...),似乎也遇到了同样的问题,即它无法处理变量文件名,并且我需要像以前一样动态构造SQL语句(因此无法访问临时表)。
因此,这给我留下的唯一选择就是使用非临时表并以另一种方式实现进程隔离(通过确保在任何时候都只有一个进程可以使用表,我可以想到几种方法)去做)。
它很烦人。按照我最初的意图进行操作会更加方便。这些事情中只有一件事是微不足道的,但最终却浪费了您一整天的时间…
您可以做任何您想做的事情。亚伦的答案不是很完整。
他的方法是正确的,直到在内部查询中创建临时表。然后,您需要将结果插入外部查询的表中。
以下代码片段获取文件的第一行并将其插入表@Lines中:
declare @fieldsep char(1) = ','; declare @recordsep char(1) = char(10); declare @Lines table ( line varchar(8000) ); declare @sql varchar(8000) = ' create table #tmp ( line varchar(8000) ); bulk insert #tmp from '''+@filename+''' with (FirstRow = 1, FieldTerminator = '''+@fieldsep+''', RowTerminator = '''+@recordsep+'''); select * from #tmp'; insert into @Lines exec(@sql); select * from @lines