quarta-feira, 23 de março de 2016

Attention events can cause open transactions and blocking in SQL Serve

Attention events can cause open transactions and blocking in SQL Server



Wondering what causes Attention events in a SQL server Profiler trace and how these events can result into severe blocking problems? I will attempt to provide some answers in this post.
First of all let’s talk about what Attentions events are and what may cause them. According to BOL –
“The Attention event class indicates that an attention event, such as cancel, client-interrupt requests, or broken client connections, has occurred. Cancel operations can also be seen as part of implementing data access driver time-outs”
There are three most common reasons of Attention events that I have seen in my experience so far. In each case, Attention events were causing open transactions and resulting in massive blocking issues. Here are those three scenarios -
1. Query Cancellation
User may cancel the currently executing query/batch request at any time – may be the user got tired of waiting on the screen! If the query or the batch was in an explicit user transaction (BEGIN TRAN …. END TRAN), these Attention events could result in open transactions and severe blocking problems. We can reproduce this scenario from within SQL Server Management Studio. Try the following –
  • Run a SQL Server Profiler trace with the following events selected – Attention, SQL:BatchCompleted, SQL:BatchStarting, SQL:StmtCompleted, SQL:StmtStarting
  • Open Management Studio and run the following batch –
 USE TEMPDB 
 GO 
 
 IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID (N'[DBO].[TEST]') AND TYPE in (N'U')) 
 DROP TABLE [DBO].[TEST] 
 GO 
 
 --Create a Test table and Insert few records in it 
 
 CREATE TABLE TEST (C1 INT, C2 VARCHAR (100)) 
 GO 
 
 INSERT INTO TEST VALUES (1, 'AAA') 
 GO 
 INSERT INTO TEST VALUES (2, 'BBB') 
 GO 
 
 -- Simulate a user transaction that will take a several seconds to execute 
 -- we will use the WAITFOR command to simulate such a transaction 
 
 BEGIN TRAN 
 UPDATE TEST SET C2 = 'MODIFY1' 
 WHERE C1 = 1 
 WAITFOR DELAY '00:00:45' 
 COMMIT TRAN
  • While the transaction is in progress, click on the Cancel option (red square button on the toolbar) -
  • You will notice an Attention event in Profiler trace.
2_Profiler_Showing_Attention
  • In the trace, you will also notice that the COMMIT TRAN statement never executed and so the transaction is still open. You can confirm that by running the following statement from the same query window in which you had cancelled the query
SELECT @@TRANCOUNT 
GO
  • Now let’s see what kind of locks are being held by this open transaction. Run a select query on the sys.dm_tran_locks DMV (you may want to filter the result on your session to exclude extra noise). You should notice an exclusive (X) lock on the row (RID), and Intent exclusive (IX) locks on the Page and the table. So with those locks in place, if another user starts a query that needs a conflicting lock on any of these resources, you will see blocking. For example, if another user/transaction/query tries to SELECT/UPDATE/DELETE the same row, it will get blocked by the open transaction. Try running this SELECT query in a another query window
SELECT * FROM TEST WHERE C1=1 
GO 
  • Open the “Activity – All Blocking Transactions” server report to analyze the blocking chain (right click on your SQL instance in Object Explorer -> Reports -> Standard Reports -> Activity – All Blocking Transactions)
6_Blocking_Transaction_report
So the question is how long will this blocking go on for? Actually this blocking chain will go indefinitely until one of the following events occurs –
  • The open transaction is committed or rolled back manually, since we just saw that SQL server will not automatically commit or rollback the transaction on Attention events.
  • The connection (or SQL Server session) that started the transaction is terminated. This will happen when the user disconnects from the application.
  • The connection is recycled in a connection the pool, if the application is using connection pooling.
2. Query Timeouts:
This is the second most common reason I have seen in my experience, which causes Attention events, open transactions and blocking issues. The default query timeout in SQL Server is 0, which means that a query will run indefinitely until completion. However, application developers can change the default query timeout value in SQL Server connection string. Also, OLEDB and ODBC providers of SQL Server have non-zero query timeout values as discussed in this article – DBA’s Quick Guide to Timeouts. Query timeouts, if not handled properly, can cause blocking issues in SQL Server. Let’s see how that can happen -
  • Open a new query editor window in Management Studio that will prompt you to specify the authentication details. You can do that by clicking on the File menu –> New –> Database Engine Query. On the Connect to Database Engine screen, click on the Option >> button and change the Execution time-out setting from default of 0 to 15. The default value of 0 means the query will run indefinitely. Here is a snapshot-
9_SSMS_Change_Execution_Timeout
  • Restart the Profiler trace and run the following batch from the query window that you just opened –
 USE TEMPDB 
 GO 
 
 -- Run a TSQL batch request that would take a few seconds to execute 
 -- We will use the WAITFOR command to simulate such a query 
 
 IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[TEST2]') AND TYPE IN (N'U')) 
 DROP TABLE [DBO].[TEST2] 
 GO 
 
 --Create a Test table and Insert few records in it 
 
 CREATE TABLE TEST2 (C1 INT, C2 VARCHAR (100)) 
 GO 
 
 INSERT INTO TEST2 VALUES (1, 'AAA') 
 GO 
 INSERT INTO TEST2 VALUES (2, 'BBB') 
 GO 
 
 --Start a user transaction that would take about 10 seconds to complete
 
 BEGIN TRAN 
 UPDATE TEST2 SET C2 = 'MODIFY1' 
 WHERE C1 = 1 
 WAITFOR DELAY '00:00:45' 
 COMMIT TRAN
After 15 seconds, which is the query timeout value that we had set while connecting to the server, the batch will terminate with the following timeout error –
Msg -2, Level 11, State 0, Line 0 Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
  • You will also notice an Attention event in the trace. If you check the open transaction count by running the SELECT @@TRANCOUNT query from the same query window in which you were running the batch, it will return 1, meaning that there is one open transaction. If you run a SELECT query on the sys.dm_tran_locks DMV, you will notice the same set of locks being held by the open transaction as you saw in the first scenario. If the application is not handling the query timeout errors and rolling back open transactions, it will result in blocking.
What about Lock timeout errors? Will they also result in Attention events?
The answer is NO! Lock Timeout errors do not cause Attention events and execution will proceed to the next statements in the transaction. See it for yourself!
  • Run the following batch from a new query window (if you are using an existing query window that is already open, make sure to roll back all open transactions in that window) -
     
     USE TEMPDB 
     GO 
     
     -- Create a Test table and Insert some rows in it 
     IF EXISTS (SELECT * FROM SYS.OBJECTS WHERE OBJECT_ID = OBJECT_ID(N'[DBO].[TEST3]') AND TYPE IN (N'U')) 
     DROP TABLE [DBO].[TEST3] 
     GO 
     
     CREATE TABLE TEST3 (C1 INT, C2 VARCHAR (100)) 
     GO 
     
     INSERT INTO TEST3 VALUES (1, 'AAA') 
     GO 
     
     INSERT INTO TEST3 VALUES (2, 'BBB') 
     GO 
     
     -- Run a TSQL batch request that will start a 
     -- transaction but do not COMMIT or ROLLBACK the transaction 
     -- I am doing this to create a classic blocking 
     -- scenario to test lock timeout errors 
     
     BEGIN TRAN 
     UPDATE TEST3 SET C2 = 'MODIFY1' 
     WHERE C1 = 1 
     GO
  • Restart the Profiler trace and run the following batch in a second query editor window –
USE Tempdb
 GO
 
 SET LOCK_TIMEOUT 5000 
 GO 
 
 BEGIN TRAN 
 UPDATE TEST3 SET C2 = 'MODIFYAGAIN' 
 WHERE C1 = 1 
 COMMIT TRAN
  • Expectedly, after 5 seconds, the batch will terminate with a lock timeout error (Error 1222) –
Msg 1222, Level 16, State 45, Line 3 Lock request time out period exceeded. The statement has been terminated.
  • However, you will not see an Attention event in the Profiler trace this time. You will also notice that after the lock timeout error occurred, SQL server continued with the execution of the batch and finally committed the transaction even though the UPDATE statement had failed. If you run a SELECT @@TRANCOUNT in the same query window, it will return 0, meaning there is no open transaction
12_Trace_Lock_timeout
3. Applications not processing the result set completely
I have seen this problem while working with a customer who had an ODBC application fetching data from SQL Server. The application was coded to ask for a result set in a cursor, fetch the first few records (and not all of the requested rows) and discard the rest. This problem has been described in detail in this blog. Unfortunately, I don’t have an application to demonstrate this behavior. But if you are noticing the following characteristics with your application and seeing a large number of Attention events and blocking chains in SQL Server, this could be the case.
  • You notice a large number of Attention events in the a SQL Server profiler trace and you have confirmed that they are not caused by user cancellation or query timeouts
  • You are seeing a pattern in the trace showing that the Attention event arrived right after the batch started, generally milliseconds afterwards and not something like a 30 second query timeout. Here is a snapshot of this pattern that I was seeing in SQL traces –
Attention_Events
  • You are seeing ASYNC_NETWORK_IO waits in SQL Server, which is an indication that the application is not processing the result set completely.
Solutions:
So now that we know how Attention events can result in open transactions and blocking problems, what can we do to resolve this problem? Here are two solutions that I have successfully tried while working with customers –
  • Check after each transaction (or before starting a new transaction in the same session) to see if the transaction is complete by using the following statement:
IF @@TRANCOUNT > 0 ROLLBACK
  • Use SET XACT_ABORT ON for the connection, or in any stored procedures which begin transactions and are not cleaning up following an error. In the event of a run-time error, this setting will abort any open transactions and return control to the client. Note that T-SQL statements following the statement which caused the error will not be executed. It’s a good practice to set XACT_ABORT to on before starting any user transactions so that any batch terminating error (such as Attention events) would roll back the entire transaction. If you can’t modify the application easily to specify XACT_ABORT, you can try the USER_OPTIONS configuration setting in SQL Server to turn on XACT_ABORT on an entire instance of SQL Server. The below snapshot shows how to turn on XACT_ABORT on an instance of SQL Server –
12_XACT_ABORT
Important: This (or setting it at the connection level) does not guarantee desired behavior in case of an Attention event though, since application code can override the setting. The only completely reliable way would be to set XACT_ABORT to ON before every BEGIN TRAN

SOURCE:  https://blogs.msdn.microsoft.com

Hunting down the origins of FETCH API_CURSOR and sp_cursorfetch

Hunting down the origins of FETCH API_CURSOR and sp_cursorfetch

So picture the following scenario on a SQL Server 2008 R2 instance (an amalgam of various DBA situations you've no doubt seen before)… 
You get a call from the application team reporting slow performance on a specific service.  They don’t know why it is slow but they do know the session that is running too slow based on the connection and session properties.  They tell you that the issue is happening right now and that they are seeing the offending session issue the following RPC:Completed events in SQL Profiler:
·        exec sp_cursorfetch 180150003,32,1,1
·        exec sp_cursorfetch 180150003,32,1,1
·        exec sp_cursorfetch 180150003,32,1,1
·        exec sp_cursorfetch 180150003,32,1,1
They ask you to take it over and find out what is happening. You’re not sure what the original query is or why this is showing up, but you see the session id they are pointing to is “53” (and you don’t remember the syntax around pulling SQL text “the new way” – so you execute the following ):
DBCC INPUTBUFFER (53)
This returns:
               FETCH API_CURSOR0000000000000004
You do a few quick searches and it seems to have a relationship with server-side cursors. 
You try activity monitor – just in case – but again, no luck:
clip_image001
You take out the new DMV queries – but your query against sys.dm_exec_requests isn’t turning up anything for session id 53 because the executions of this cursor are erratic and you're not timing it (but SQL Profiler does show it plodding along in fits and starts).
You then run the following query against sys.dm_exec_connections and see if that turns up anything useful based on the most recent SQL handle:
SELECT t.text
FROM sys.dm_exec_connections c
CROSS APPLY sys.dm_exec_sql_text (c.most_recent_sql_handle) t
WHERE session_id = 53
 
This returns:
FETCH API_CURSOR0000000000000004
Didn’t help.  
So what about other DMVs?  You eventually find a reference to the sys.dm_exec_cursors DMV and see it can tell you about open cursors, their properties and associated SQL handle.  But you're not sure the SQL Handle will be any help because it hasn't been helpful with the other DMVs:
SELECT c.session_id, c.properties, c.creation_time, c.is_open, t.text
FROM sys.dm_exec_cursors (53) c
CROSS APPLY sys.dm_exec_sql_text (c.sql_handle) t
What do we get this time? Something a bit more useful:
clip_image003
From the results we see the properties of the cursor (using scroll locks) and we also see when it was created – and we see the original query text (unlike the cryptic FETCH API_CURSOR business or the sp_cursorfetch).  We see it was a SELECT * FROM dbo.FactResellerSales.
Now this isn’t to say that SQL Profiler wouldn’t have helped in this situation – but in this case the cursor was defined before the developers captured the downstream activity.  
If they had been tracing it sooner, you might have seen something like this (and then see it followed by sp_cursorfetch):
declare @p1 int
set @p1=180150003
declare @p3 int
set @p3=2
declare @p4 int
set @p4=2
declare @p5 int
set @p5=-1
exec sp_cursoropen @p1 output,N'SELECT * FROM dbo.FactResellerSales',@p3 output,@p4 output,@p5 output
select @p1, @p3, @p4, @p5
 
But in a situation where you’re reacting to an incident (fox has already left the henhouse, so to speak), chances are you weren’t tracing this activity.  And if that’s the case, you’ve now found one reason to use sys.dm_exec_cursors if you didn’t already have one.

SOURCE: http://www.sqlskills.com 

terça-feira, 16 de fevereiro de 2016

How to Add Front-End Login Page and Widgets in WordPress

Do you want to add front-end login feature to your WordPress site? Sending users to the default login page usually redirects them to the WordPress admin area. This is very confusing and is bad for user experience. Wouldn’t it be nice if users can login to your WordPress site directly from the front-end? In this article, we will show you how to add a front-end login page in WordPress.
Adding frontend login in WordPress

Why and When You Need Front-end Login in WordPress?

By default, WordPress sends users to their profile page in WordPress admin area when they sign in. Now if there is something they can do in the admin area, like writing a post, then it is understandable.
However, in case of WordPress membership sites, all your users don’t need access to the dashboard. In fact, many users will probably feel a bit confused after login.
Allowing users to login from the front-end of your website will improve user experience. Users will be able to continue doing what they wanted to do.
Having said that, let’s see how you can add a frontend login page or a widget in WordPress.

Adding Frontend Login in WordPress

First thing you need to do is install and activate the Theme My Login plugin.
Upon activation, the plugin will create pages for login, logout, forget password, and registration.
Theme My Login Pages for frontend login, registration, password reset, and logout.
You can simply visit these pages in your browser to see these forms in action.
Preview of a frontend login page in WordPress
Theme My Login works out of the box, but you can also adjust the plugin settings to meet your needs. Simply visit TML page in admin area to configure plugin settings.
Theme My Login Settings
The first option allows you to load plugin’s default stylesheet. If you are having trouble with the display of forms on your website, then you can uncheck this option.
Theme My Login can also allow your users to login with email address, username, or both.

Theme My Login Modules

Theme My Login comes with different modules packed right into the plugin. You can enable them based on your own requirements. Simply check the module you want to enable.
Once you save the plugin settings, you will notice a settings page added under the TML menu for each module you enable.
Let’s take a look at what each module does and how to use them.
1. Custom Email
This module allows you to change emails sent by WordPress to users and site admins. After enabling this module you can customize email messages by visiting TML » Email tab.
Customize emails sent by WordPress
If you are having trouble sending or receiving WordPress emails, then check our guide on how to fix WordPress not sending email issue.
2. Custom Passwords
By default WordPress sends users an email asking them to visit your website to complete registration by setting up a password. By using custom passwords module you can allow users to choose a password during registration.
This module does not have a settings page. Enabling it will simply add password fields to the registration form on your website.
Allowing users to set custom passwords on registration page in WordPress
3. Custom Redirection
By default when a user logs in, WordPress sends them to their profile page in the admin area. Custom redirection module allows you to change this behavior.
After enabling this module you need to visit TML » Redirection to set up your settings.
Redirect users when they login or logout in WordPress
The plugin allows you to configure redirection for each user role on your site. This means you can set different rules for an Administrators, author and other user roles.
There are three options for both login and logout redirects. You can choose the default WordPress behavior which will send users to their profile or login page. You can choose Referer, which will send users to the page they came from. Lastly, you can choose “custom” which send users to a specific URL when they login or logout.
4. Custom User Links
This module allows you to add custom links for users. These links will be shown in Theme My Login widget. After enabling this module, you need to visit TML » Custom Links tab to edit links.
Adding custom links to Theme My Login widget
5. Recaptcha
As the name suggests, this modules allows you to show recaptcha on registration pages. After enabling it, you need to visit TML » reCAPTCHA tab to configure it.
Adding recaptcha to registration form in WordPress using Theme my login
Simply enter your site key and secret key and click save changes. You can generate site key and secret key by visiting the reCAPTCHA website.
6. Security
This module allows you to improve the security of your login pages. After enabling it, you need to visit TML » Security to configure the settings.
Improving security of your login forms
You can make a website completely private by forcing users to login before they can view the site. You can also disable access to wp-login.php file. Lastly, you can limit login attempts to protect your site from brute force attacks. Take a look at our guide on why you should limit login attempts in WordPress to learn more.
7. Themed Profiles
Themed profiles module allows users to edit their profiles on the front-end. After enabling this module, you need to visit TML » Themed Profiles tab to configure it.
Allow users to edit their profiles in frontend
Simply select the user roles for themed profiles and user roles with access to wp-admin directory.
8. User Moderation
Opening user registration on a site means that you will have to deal with spam user registrations.
Theme my login makes it easier to combat spam registration with user moderation module. After enabling this module, you need to visit TML » Moderation to configure it.
Moderate user registrations
You can choose between email confirmation method or require each registration to be manually approved by an administrator.

Adding Frontend Login Form in WordPress Sidebar Widget

Apart from creating the login, registration, and password reset pages, Theme My Login also comes with a handy widget. You can add this widget to a sidebar and allow users to login from anywhere on your site.
Simply go to Appearance » Widgets and add Theme My Login widget to a sidebar.
Login from frontend sidebar in WordPress

quinta-feira, 28 de janeiro de 2016

BULK INSERT (Transact-SQL)

BULK INSERT (Transact-SQL)

SQL Server 2014
Importa um arquivo de dados para uma tabela ou exibição de banco de dados em um formato especificado pelo usuário no SQL Server
Aplica-se a: SQL Server (do SQL Server 2008 à versão atual).
Ícone de vínculo de tópico Convenções da sintaxe Transact-SQL

BULK INSERT 
   [ database_name . [ schema_name ] . | schema_name . ] [ table_name | view_name ] 
      FROM 'data_file' 
     [ WITH 
    ( 
   [ [ , ] BATCHSIZE = batch_size ] 
   [ [ , ] CHECK_CONSTRAINTS ] 
   [ [ , ] CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' } ] 
   [ [ , ] DATAFILETYPE = 
      { 'char' | 'native'| 'widechar' | 'widenative' } ] 
   [ [ , ] FIELDTERMINATOR = 'field_terminator' ] 
   [ [ , ] FIRSTROW = first_row ] 
   [ [ , ] FIRE_TRIGGERS ] 
   [ [ , ] FORMATFILE = 'format_file_path' ] 
   [ [ , ] KEEPIDENTITY ] 
   [ [ , ] KEEPNULLS ] 
   [ [ , ] KILOBYTES_PER_BATCH = kilobytes_per_batch ] 
   [ [ , ] LASTROW = last_row ] 
   [ [ , ] MAXERRORS = max_errors ] 
   [ [ , ] ORDER ( { column [ ASC | DESC ] } [ ,...n ] ) ] 
   [ [ , ] ROWS_PER_BATCH = rows_per_batch ] 
   [ [ , ] ROWTERMINATOR = 'row_terminator' ] 
   [ [ , ] TABLOCK ] 
   [ [ , ] ERRORFILE = 'file_name' ] 
    )] 

database_name
É o nome do banco de dados no qual a tabela ou exibição especificada reside. Se não for especificado, ele será o banco de dados atual.
schema_name
É o nome do esquema da tabela ou exibição. schema_name será opcional se o esquema padrão do usuário que está executando a operação de importação em massa for o esquema da tabela ou exibição especificada. Se schema não for especificado e o esquema padrão do usuário que está executando a operação de importação em massa for diferente da tabela ou exibição especificada, o SQL Server retornará uma mensagem de erro e a operação de importação em massa será cancelada.
table_name
É o nome da tabela ou exibição para a qual os dados serão importados em massa. Só podem ser usadas exibições nas quais todas as colunas se referem à mesma tabela base. Para obter mais informações sobre as restrições de carregamento de dados em exibições, consulte INSERT (Transact-SQL).
' data_file '
É o caminho completo do arquivo de dados que contém dados a serem importados na tabela ou exibição especificada. BULK INSERT pode importar dados de um disco (inclusive rede, disco flexível, disco rígido e assim por diante).
data_file deve especificar um caminho válido do servidor no qual o SQL Server é executado. Se data_file for um arquivo remoto, especifique o nome UNC (Convenção Universal de Nomenclatura). Um nome UNC tem o formato \\Systemname\ShareName\Path\FileName. Por exemplo, \\SystemX\DiskZ\Sales\update.txt.
BATCHSIZE =batch_size
Especifica o número de linhas em um lote. Cada lote é copiado para o servidor como uma transação. Em caso de falha, o SQL Server confirmará ou reverterá a transação para cada lote. Por padrão, todo os dados no arquivo de dados especificado são um lote. Para obter informações sobre considerações de desempenho, consulte "Comentários", posteriormente neste tópico.
CHECK_CONSTRAINTS
Especifica que todas as restrições na tabela ou exibição de destino devem ser verificadas durante a operação de importação em massa. Sem a opção CHECK_CONSTRAINTS, quaisquer restrições CHECK e FOREIGN KEY são ignoradas e, depois da operação, a restrição na tabela é marcada como não confiável.
Observação Observação
As restrições UNIQUE e PRIMARY KEY são sempre impostas. Durante a importação para uma coluna de caracteres que é definida com uma restrição NOT NULL, BULK INSERT insere uma cadeia de caracteres em branco quando não há um valor no arquivo de texto.
Em algum momento, você deve examinar as restrições na tabela inteira. Se a tabela não estava vazia antes da operação de importação em massa, o custo de revalidação da restrição poderá exceder o custo da aplicação de restrições CHECK aos dados incrementais.
Uma situação em que talvez convenha desabilitar as restrições (o comportamento padrão) é quando os dados de entrada contiverem linhas que violam restrições. Com as restrições CHECK desabilitadas, é possível importar os dados e usar instruções Transact-SQL para remover os dados inválidos.
Observação Observação
A opção de MAXERRORS não se aplica à verificação de restrição.
CODEPAGE = { 'ACP' | 'OEM' | 'RAW' | 'code_page' }
Especifica a página de código dos dados no arquivo de dados. CODEPAGE só será relevante se os dados contiverem colunas char, varchar ou text com valores de caractere maiores que 127 ou menores que 32.
Observação Observação
A Microsoft recomenda que você especifique um nome de agrupamento para cada coluna em um arquivo de formato.
Valor de CODEPAGE
Descrição
ACP
As colunas do tipo de dados char, varchar ou text são convertidas da página de código ANSI/Microsoft Windows (ISO 1252) para a página de código do SQL Server.
OEM (padrão)
Colunas do tipo de dados char, varchar ou text são convertidas da página de código OEM do sistema para a página de código do SQL Server.
raw
Nenhuma conversão de uma página de código em outra ocorre; essa opção é a mais rápida.
code_page
Um número de página de código específico, por exemplo, 850.
Observação importante Importante
O SQL Server não dá suporte à página de código 65001 (codificação UTF-8).
DATAFILETYPE = { 'char' | 'native' | 'widechar' | 'widenative' }
Especifica que BULK INSERT executa a operação de importação usando o valor de tipo de arquivo de dados especificado.
Valor DATAFILETYPE
Todos os dados representados em:
char (padrão)
Formato de caractere.
Para obter mais informações, consulte Usar o formato de caractere para importar ou exportar dados (SQL Server).
nativo
Tipos de dados (banco de dados) nativo. Crie o arquivo de dados nativo por meio da importação de dados em massa do SQL Server por meio do utilitário bcp.
O valor nativo oferece uma alternativa de alto desempenho ao valor char.
Para obter mais informações, consulte Usar o formato nativo para importar ou exportar dados (SQL Server).
widechar
Caracteres unicode.
Para obter mais informações, consulte Usar o formato de caractere Unicode para importar ou exportar dados (SQL Server).
widenative
Tipos de dados nativos (banco de dados), exceto em colunas char, varchar e text, nas quais os dados são armazenados como Unicode. Crie o arquivo de dados widenative por meio da importação de dados em massa do SQL Server por meio do utilitário bcp.
O valor widenative oferece uma alternativa de alto desempenho para widechar. Se o arquivo de dados contiver caracteres ANSI estendidos, especifique widenative.
Para obter mais informações, consulte Usar o formato nativo Unicode para importar ou exportar dados (SQL Server).
FIELDTERMINATOR ='field_terminator'
Especifica o terminador de campo a ser usado para os arquivos de dados char e widechar. O terminador de campo padrão é \t (caractere de tabulação). Para obter mais informações, consulte Especificar terminadores de campo e linha (SQL Server).
FIRSTROW =first_row
Especifica o número da primeira linha a ser carregada. O padrão é a primeira linha no arquivo de dados especificado. FIRSTROW é baseado em 1.
Observação Observação
O atributo FIRSTROW não tem o objetivo de ignorar cabeçalhos de coluna. Não há suporte para ignorar cabeçalhos por parte da instrução BULK INSERT. Ao ignorar linhas, o Mecanismo de Banco de Dados do SQL Server examina somente os terminadores de campo e não valida os dados nos campos das linhas ignoradas.
FIRE_TRIGGERS
Especifica que qualquer gatilho de inserção definido na tabela de destino seja executado durante a operação de importação em massa. Se os gatilhos forem definidos para operações INSERT na tabela de destino, eles serão disparados para cada lote concluído.
Se FIRE_TRIGGERS não for especificado, nenhum gatilho de inserção será executado.
FORMATFILE ='format_file_path'
Especifica o caminho completo de um arquivo de formato. Um arquivo de formato descreve o arquivo de dados que contém as respostas armazenadas criadas por meio do utilitário bcp na mesma tabela ou exibição. O arquivo de formato deverá ser usado se:
  • O arquivo de dados contiver colunas maiores ou menos colunas que a tabela ou exibição.
  • As colunas estiverem em uma ordem diferente.
  • Os delimitadores de coluna variarem.
  • Houver outras alterações no formato de dados. Os arquivos de formato em geral são criados por meio do utilitário bcp e modificados com um editor de texto conforme necessário. Para obter mais informações, consulte Utilitário bcp.
KEEPIDENTITY
Especifica que o valor, ou valores, de identidade no arquivo de dados importado deve ser usado para a coluna de identidade. Se KEEPIDENTITY não for especificado, os valores de identidade dessa coluna serão verificados, mas não importados e o SQL Server atribuirá valores exclusivos automaticamente com base nos valores de semente e de incremento especificados durante a criação da tabela. Se o arquivo de dados não contiver valores para a coluna de identidade na tabela ou exibição, use um arquivo de formato para especificar que a coluna de identidade na tabela ou exibição deve ser ignorada ao importar dados. O SQL Server atribui valores exclusivos para a coluna automaticamente. Para obter mais informações, consulte DBCC CHECKIDENT (Transact-SQL).
Para obter mais informações sobre como manter valores de identificação, consulte Manter valores de identidade ao importar dados em massa (SQL Server).
KEEPNULLS
Especifica que colunas vazias devem reter um valor nulo durante a operação de importação em massa, em vez de ter qualquer valor padrão para as colunas inseridas. Para obter mais informações, consulte Manter valores nulos ou use os valores padrão durante a importação em massa (SQL Server).
KILOBYTES_PER_BATCH = kilobytes_per_batch
Especifica o número aproximado de quilobytes (KB) de dados por lote como kilobytes_per_batch. Por padrão, KILOBYTES_PER_BATCH é desconhecido. Para obter informações sobre considerações de desempenho, consulte “Comentários”, posteriormente neste tópico.
LASTROW=last_row
Especifica o número da última linha a ser carregada. O padrão é 0, que indica a última fila no arquivo de dados especificado.
MAXERRORS = max_errors
Especifica o número máximo de erros de sintaxe permitido nos dados antes que a operação de importação em massa seja cancelada. Cada linha que não pode ser importada pela operação de importação em massa é ignorada e contada como um erro. Se max_errors não for especificado, o padrão será 10.
Observação Observação
A opção MAX_ERRORS não se aplica a verificações de restrição ou à conversão dos tipos de dados money e bigint.
ORDER ( { column [ ASC | DESC ] } [ ,... n ] )
Especifica como os dados no arquivo de dados são classificados. O desempenho da importação em massa será melhor se os dados importados forem classificados de acordo com o índice clusterizado na tabela, se houver. Se o arquivo de dados for classificado em outra ordem, ou seja, diferente da ordem de uma chave de índice clusterizado, ou se não houver nenhum índice clusterizado na tabela, a cláusula ORDER será ignorada. Os nomes de coluna fornecidos devem ser nomes válidos na tabela de destino. Por padrão, a operação de inserção em massa supõe que o arquivo de dados não esteja ordenado. Para obter uma importação em massa otimizada, o SQL Server também valida que os dados importados sejam classificados.
n
É um espaço reservado que indica que várias colunas podem ser especificadas.
ROWS_PER_BATCH =rows_per_batch
Indica o número aproximado de linhas de dados no arquivo de dados.
Por padrão, todos os dados de arquivo são enviados ao servidor como uma única transação, e o número de linhas no lote é desconhecido para o otimizador de consulta. Se você especificar ROWS_PER_BATCH (com um valor > 0), o servidor usará esse valor para otimizar a operação da importação em massa. O valor especificado para ROWS_PER_BATCH deve ser aproximadamente igual ao número real de linhas. Para obter informações sobre considerações de desempenho, consulte “Comentários”, posteriormente neste tópico.
ROWTERMINATOR ='row_terminator'
Especifica o terminador de linha a ser usado para os arquivos de dados char e widechar. O terminador de linha padrão é \r\n (caractere de nova linha). Para obter mais informações, consulte Especificar terminadores de campo e linha (SQL Server).
TABLOCK
Especifica que um bloqueio no nível de tabela é adquirido durante a operação de importação em massa. Uma tabela pode ser carregada simultaneamente através de vários clientes se não tiver nenhum índice e TABLOCK for especificado. Por padrão, o comportamento de bloqueio é determinado pela opção de tabela bloqueio de tabela em carregamento em massa. Manter um bloqueio durante a operação de importação em massa reduz a contenção de bloqueio na tabela e em alguns casos pode melhorar significativamente o desempenho. Para obter informações sobre considerações de desempenho, consulte “Comentários”, posteriormente neste tópico.
ERRORFILE ='file_name'
Especifica o arquivo usado para coletar linhas com erros de formatação e que não podem ser convertidas em um conjunto de linhas OLE DB. Essas linhas são copiadas do arquivo de dados para esse arquivo de erro "no estado em que se encontram".
O arquivo de erro é criado quando o comando é executado. Ocorrerá um erro se o arquivo já existir. Além disso, é criado um arquivo de controle com a extensão .ERROR.txt. Ele faz referência a cada linha do arquivo de erro e fornece um diagnóstico de erros. Assim que os erros forem corrigidos, os dados poderão ser carregados.

O BULK INSERT impõe validação estrita de dados e verificações de dados lidos de um arquivo que podem provocar falha nos scripts existentes quando executadas com dados inválidos. Por exemplo, BULK INSERT verifica se:
  • As representações nativas de tipos de dados float ou real são válidas.
  • Dados Unicode têm um comprimento de byte padrão.

Conversões do tipo de dados de cadeia de caracteres em decimal

As conversões do tipo de dados de caracteres em decimal usada em BULK INSERT seguem as mesmas regras que a função Transact-SQL CONVERT, que rejeita cadeias de caracteres que representam valores numéricos que usam notação científica. Portanto, BULK INSERT trata essas cadeias de caracteres como valores inválidos e relata erros de conversão.
Como solução alternativa para esse comportamento, use um arquivo de formato para importar em massa dados float de notação científica em uma coluna decimal. No arquivo de formato, descreva explicitamente a coluna como dados real ou float. Para obter mais informações sobre esses tipos de dados, consulte flutuante e real (Transact-SQL).
Observação Observação
Os arquivos de formato representam dados real como o tipo de dados SQLFLT4 e dados float como o tipo de dados SQLFLT8. Para obter informações sobre arquivos de formato não XML, consulte Especificar tipo de armazenamento de arquivo usando bcp (SQL Server).

Exemplo de importação de um valor numérico que usa notação científica

Este exemplo usa a seguinte tabela:
CREATE TABLE t_float(c1 float, c2 decimal (5,4));
O usuário quer importar dados em massa para a tabela t_float. O arquivo de dados, C:\t_float-c.dat, contém dados float de notação científica; por exemplo:
8.0000000000000002E-28.0000000000000002E-2
Entretanto, BULK INSERT não pode importar esses dados diretamente em t_float, porque sua segunda coluna, c2, usa o tipo de dados decimal. Portanto, um arquivo de formato é necessário. O arquivo de formato deve mapear os dados float de notação científica para o formato decimal de coluna c2.
O arquivo de formato a seguir usa o tipo de dados SQLFLT8 para mapear o segundo campo de dados para a segunda coluna:
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\t" MAX_LENGTH="30"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="30"/> </RECORD> <ROW>
<COLUMN SOURCE="1" NAME="c1" xsi:type="SQLFLT8"/>
<COLUMN SOURCE="2" NAME="c2" xsi:type="SQLFLT8"/> </ROW> </BCPFORMAT>
Para usar esse arquivo de formato (com o nome de arquivo C:\t_floatformat-c-xml.xml) para importar os dados de teste para a tabela de teste, emita a seguinte instrução Transact-SQL:
BULK INSERT bulktest..t_float
FROM 'C:\t_float-c.dat' WITH (FORMATFILE='C:\t_floatformat-c-xml.xml');
GO

Tipos de dados para exportação ou importação em massa de documentos SQLXML

Para exportar ou importar dados SQLXML em massa, use um dos tipos de dados a seguir em seu arquivo de formato:
Tipo de dados
Efeito
SQLCHAR ou SQLVARCHAR
Os dados são enviados na página de código do cliente ou na página de código implícita pelo agrupamento). O efeito é o mesmo que especificar DATAFILETYPE ='char' sem especificar um arquivo de formato.
SQLNCHAR ou SQLNVARCHAR
Os dados são enviados como Unicode. O efeito é o mesmo que especificar DATAFILETYPE = 'widechar' sem especificar um arquivo de formato.
SQLBINARY ou SQLVARBIN
Os dados são enviados sem qualquer conversão.

Para obter uma comparação da instrução BULK INSERT, da instrução INSERT ... SELECT * FROM OPENROWSET(BULK...) e do comando bcp, consulte Importação e exportação em massa de dados (SQL Server).
Para obter informações sobre como preparar dados para importação em massa, consulte Preparar dados para exportar ou importar em massa (SQL Server).
A instrução BULK INSERT pode ser executada dentro de uma transação definida pelo usuário para importar dados em uma tabela ou exibição. Opcionalmente, para usar várias correspondências para obter dados de importação em massa, uma transação pode especificar a cláusula BATCHSIZE na instrução de BULK INSERT. Se uma transação de vários lotes for revertida, todo o lote enviado pela transação ao SQL Server será revertido.

Importando dados de um arquivo CSV

Arquivos CSV (valores separados por vírgula) não têm suporte em operações de importação em massa do SQL Server. No entanto, em alguns casos, um arquivo CSV pode ser usado como o arquivo de dados para uma importação em massa de dados no SQL Server. Para obter informações sobre os requisitos da importação de dados de um arquivo de dados CSV, consulte Preparar dados para exportar ou importar em massa (SQL Server).

Para obter informações sobre quando as operações de inserção de linhas executadas por importações em massa são registradas no log de transações, consulte Pré-requisitos para log mínimo em importação em massa.

Ao usar um arquivo de formato com BULK INSERT, você pode especificar até somente 1024 campos. Isso é o mesmo que o número máximo de colunas permitido em uma tabela. Se você usar BULK INSERT com um arquivo de dados que contém mais de 1024 campos, o BULK INSERT gerará o erro 4822. O utilitário bcp não tem esta limitação; portanto, para arquivos de dados que contêm mais de 1024 campos, use o comando bcp.

Se o número de páginas a ser liberado em um único lote exceder um limite interno, poderá ocorrer um exame completo do pool de buffers para identificar quais páginas devem ser liberadas quando o lote for confirmado. Esse exame completo pode prejudicar o desempenho da importação em massa. Um caso provável de exceder o limite interno ocorre quando um pool de buffers grande é combinado com um subsistema de E/S lento. Para evitar estouros de buffer em máquinas grandes, não use a dica TABLOCK (que removerá as otimizações em massa) ou use um tamanho de lote menor (que preserva as otimizações em massa).
Como os computadores variam, é recomendável testar vários tamanhos de lote com seu carregamento de dados para descobrir o que funciona melhor para você.

Delegação de conta de segurança (representação)

Se um usuário usar um logon SQL Server, o perfil de segurança da conta de processo SQL Server será usado. Um logon que usa a autenticação do SQL Server não pode ser autenticado fora do Mecanismo de Banco de Dados. Em virtude disso, quando um comando BULK INSERT for iniciado por um logon usando a autenticação do SQL Server, a conexão com os dados será feita usando o contexto de segurança da conta de processo do SQL Server (a conta usada pelo serviço do Mecanismo de Banco de Dados do SQL Server). Para ler com êxito os dados de origem, você deverá conceder à conta usada pelo Mecanismo de Banco de Dados do SQL Server acesso aos dados de origem. Em contraste, se um usuário do SQL Server fizer logon usando a Autenticação do Windows, o usuário pode ler somente esses arquivos que podem ser acessados pela conta de usuário, independentemente do perfil de segurança do processo do SQL Server.
Ao executar a instrução BULK INSERT com sqlcmd ou osql de um computador, inserir dados no SQL Server em um segundo computador e especificar data_file em um terceiro computador por meio de um caminho UNC, poderá ocorrer um erro 4861.
Para resolver esse erro, use a Autenticação do SQL Server e especifique um logon do SQL Server que use o perfil de segurança da conta de processo do SQL Server, ou configure o Windows para habilitar a delegação de conta de segurança. Para obter informações sobre como habilitar uma conta de usuário que seja confiável para a delegação, consulte a Ajuda do Windows.
Para obter mais informações sobre essa e outras considerações de segurança para usar BULK INSERT, consulte Importar dados em massa usando BULK INSERT ou OPENROWSET(BULK...) (SQL Server).

Permissões

Requer as permissões INSERT e ADMINISTER BULK OPERATIONS. Além disso, a permissão ALTER TABLE será necessária se uma ou mais das seguintes afirmações for verdadeira:
  • Existem restrições e a opção CHECK_CONSTRAINTS não foi especificada.
    Observação Observação
    Desabilitar restrições é o comportamento padrão. Para verificar as restrições explicitamente, use a opção CHECK_CONSTRAINTS.
  • Existem gatilhos e a opção FIRE_TRIGGER não foi especificada.
    Observação Observação
    Por padrão, os gatilhos não são disparados. Para disparar gatilhos explicitamente, use a opção FIRE_TRIGGER.
  • Use a opção KEEPIDENTITY para importar valor de identidade do arquivo de dados.

A.Usando pipes para importar dados de um arquivo

O exemplo a seguir importa informações de detalhes de pedidos na tabela AdventureWorks2012.Sales.SalesOrderDetail do arquivo de dados especificado com o uso de um pipe ( | ) como o terminador de campo e |\n como o terminador de linha.
BULK INSERT AdventureWorks2012.Sales.SalesOrderDetail
   FROM 'f:\orders\lineitem.tbl'
   WITH 
      (
         FIELDTERMINATOR =' |',
         ROWTERMINATOR =' |\n'
      );

B.Usando o argumento FIRE_TRIGGERS

O exemplo a seguir especifica o argumento FIRE_TRIGGERS.
BULK INSERT AdventureWorks2012.Sales.SalesOrderDetail
   FROM 'f:\orders\lineitem.tbl'
   WITH
     (
        FIELDTERMINATOR =' |',
        ROWTERMINATOR = ':\n',
        FIRE_TRIGGERS
      );

C.Usando alimentação de linha como um terminador de linha

O exemplo a seguir importa um arquivo que usa a alimentação de linha como um terminador de linha, como uma saída UNIX:
DECLARE @bulk_cmd varchar(1000);
SET @bulk_cmd = 'BULK INSERT AdventureWorks2012.Sales.SalesOrderDetail
FROM ''<drive>:\<path>\<filename>'' 
WITH (ROWTERMINATOR = '''+CHAR(10)+''')';
EXEC(@bulk_cmd);


SOURCE: https://msdn.microsoft.com