Pergunta

Se eu executar a seguinte consulta no SQL Server 2000 Query Analyzer:

BULK INSERT  OurTable 
FROM 'c:\OurTable.txt' 
WITH (CODEPAGE = 'RAW', DATAFILETYPE = 'char', FIELDTERMINATOR = '\t', ROWS_PER_BATCH = 10000, TABLOCK)

Em um arquivo de texto que está em conformidade com o esquema do OurTable para 40 linhas, mas depois altera o formato das últimas 20 linhas (digamos que as últimas 20 linhas tenham menos campos), recebo um erro.No entanto, as primeiras 40 linhas estão comprometidas com a tabela.Há algo na maneira como estou chamando o Bulk Insert que faz com que ele não seja transacional ou preciso fazer algo explícito para forçá-lo a reverter em caso de falha?

Foi útil?

Solução

BULK INSERT atua como uma série de indivíduos INSERT instruções e, portanto, se o trabalho falhar, ele não reverterá todas as inserções confirmadas.

No entanto, ele pode ser colocado dentro de uma transação para que você possa fazer algo assim:

BEGIN TRANSACTION
BEGIN TRY
BULK INSERT  OurTable 
FROM 'c:\OurTable.txt' 
WITH (CODEPAGE = 'RAW', DATAFILETYPE = 'char', FIELDTERMINATOR = '\t', 
   ROWS_PER_BATCH = 10000, TABLOCK)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
END CATCH

Outras dicas

Você pode reverter as inserções.Para fazer isso, precisamos entender duas coisas primeiro

BatchSize

:Número de linhas a serem inseridas por transação.O padrão é o arquivo de dados inteiro.Portanto, um arquivo de dados está em transação

Digamos que você tenha um arquivo de texto com 10 linhas e a linha 8 e a linha 7 tenham alguns detalhes inválidos.Quando você insere o arquivo em massa sem especificar ou especificando o tamanho do lote , 8 de 10 são inseridos na tabela.A linha inválida, ou seja,O 8º e o 7º falharam e não foram inseridos.

Isso acontece porque o padrão MAXERRORS a contagem é 10 por transação.

Conforme MSDN:

MAXERROS:

Especifica o número máximo de erros de sintaxe permitidos nos dados antes que a operação em massa-ímpete seja cancelada.Cada linha que não pode ser importada pela operação em massa é ignorada e contada como um erro.Se max_errors não for especificado, o padrão será 10.

Portanto, para falhar em todas as 10 linhas, mesmo que uma seja inválida, precisamos definir MAXERRORS=1 e BatchSize=1 Aqui o número de BatchSize também é importante.

Se você especificar BatchSize e a linha inválida estiver dentro do lote específico, ele reverterá apenas o lote específico, não todo o conjunto de dados.Portanto, tenha cuidado ao escolher esta opção

Espero que isso resolva o problema.

Como afirmado no BATCHSIZE definição para BULK INSERT na biblioteca MSDN (http://msdn.microsoft.com/en-us/library/ms188365(v=sql.105).aspx) :

"Se isso falhar, o SQL Server confirma ou reverte a transação para cada lote..."

Concluindo, não é necessário adicionar transacionalidade ao Bulk Insert.

Tente colocá-lo dentro da transação definida pelo usuário e veja o que acontece.Na verdade, ele deve reverter conforme você descreveu.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top