Gar*_*ill 31 sql t-sql sql-server bulkinsert
我有一些这样的代码,我用来将数据文件的BULK INSERT写入表中,其中数据文件和表名是变量:
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语句(因此无法访问临时表).
所以,这只留下一个选项,即使用非临时表并以不同的方式实现进程隔离(通过确保任何时候只有一个进程可以使用表 - 我可以想到几种方法去做).
它很烦人.按照我最初的预期方式进行操作会更方便.只是其中一件应该是微不足道的事情,但最终会吃掉你整整一天的时间......
Aar*_*and 18
您始终可以在动态SQL中构造#temp表.例如,现在我猜你一直在尝试:
CREATE TABLE #tmp(a INT, b INT, c INT);
DECLARE @sql NVARCHAR(1000);
SET @sql = N'BULK INSERT #tmp ...' + @variables;
EXEC master.sys.sp_executesql @sql;
SELECT * FROM #tmp;
这使得维护(可读性)变得更加困难,但却受到范围问题的影响:
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'CREATE TABLE #tmp(a INT, b INT, c INT);
BULK INSERT #tmp ...' + @variables + ';
SELECT * FROM #tmp;';
EXEC master.sys.sp_executesql @sql;
编辑2011-01-12
鉴于我几乎2岁的答案突然被认为是不完整和不可接受的,答案也是不完整的,如何:
CREATE TABLE #outer(a INT, b INT, c INT);
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SET NOCOUNT ON; 
CREATE TABLE #inner(a INT, b INT, c INT);
BULK INSERT #inner ...' + @variables + ';
SELECT * FROM #inner;';
INSERT #outer EXEC master.sys.sp_executesql @sql;
Gor*_*off 13
可以做你想做的一切.亚伦的回答并不完整.
他的方法是正确的,直到在内部查询中创建临时表.然后,您需要将结果插入外部查询中的表中.
以下代码片段抓取文件的第一行并将其插入表@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