{"id":1584,"date":"2012-02-07T03:22:30","date_gmt":"2012-02-07T03:22:30","guid":{"rendered":"http:\/\/craftydba.com\/?p=1584"},"modified":"2012-02-16T16:46:58","modified_gmt":"2012-02-16T16:46:58","slug":"import-export-data-part-3","status":"publish","type":"post","link":"https:\/\/craftydba.com\/?p=1584","title":{"rendered":"Import &#038; Export Data &#8211; Part 3"},"content":{"rendered":"<p>The <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms162802.aspx\">BCP<\/a> command line utility is the <a href=\"http:\/\/www.cadillac.com\/flash.html\">Cadillac<\/a> of ETL programs for text based data files. It is REALLY FAST. It can perform both imports and exports and it can generate format files from existing objects.<\/p>\n<p>Today, I am going implement the same business algorithms I did earlier (Part 2) using the BCP program instead of BULK INSERT. We will be working again with the Boy Scouts of America (BSA) hypothetical database. I will be using the xp_cmdshell to execute BCP from a query window inside of SQL Server Management Studio (SSMS).<\/p>\n<p>I want to stress that the following steps should be done before, during, and after a major data load.<\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"175\" align=\"left\">\n<tbody>\n<tr>\n<td style=\"border: thin solid gray; background-color: #dbdbdb;\">TIMING<\/td>\n<td style=\"border: thin solid gray; background-color: #dbdbdb;\">TSQL COMMAND<\/td>\n<td style=\"border: thin solid gray; background-color: #dbdbdb;\">BUSINESS RULE<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">BEFORE<\/td>\n<td style=\"border: thin solid gray;\">BACKUP DATABASE<\/td>\n<td style=\"border: thin solid gray;\">Backup database before changes.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">BEFORE<\/td>\n<td style=\"border: thin solid gray;\">ALTER DATABASE<\/td>\n<td style=\"border: thin solid gray;\">Set recovery model to bulk logged.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">DURING<\/td>\n<td style=\"border: thin solid gray;\">BCP<\/td>\n<td style=\"border: thin solid gray;\">Execute ETL processes.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">DURING<\/td>\n<td style=\"border: thin solid gray;\">BACKUP LOG<\/td>\n<td style=\"border: thin solid gray;\">Keep log growth to minimum.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">AFTER<\/td>\n<td style=\"border: thin solid gray;\">ALTER DATABASE<\/td>\n<td style=\"border: thin solid gray;\">Set recovery model to full.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">AFTER<\/td>\n<td style=\"border: thin solid gray;\">BACKUP DATABASE<\/td>\n<td style=\"border: thin solid gray;\">Backup database after changes.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The BSA database has a STAGING schema for loading external data. The BCP utility in its simplest form must have the source data file match the number of columns in the target table. Therefore, we need to re-create the table to have just two fields.<\/p>\n<p>There are many arguements that can be used to change how the statement executes. Here are some used that are used in the examples below.<\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"175\" align=\"left\">\n<tbody>\n<tr>\n<td style=\"border: thin solid gray; background-color: #dbdbdb;\">BCP SWITCH<\/td>\n<td style=\"border: thin solid gray; background-color: #dbdbdb;\">ACTION<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-F<\/td>\n<td style=\"border: thin solid gray;\">first row starts at row x.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-L<\/td>\n<td style=\"border: thin solid gray;\">last row ends at row y.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-t<\/td>\n<td style=\"border: thin solid gray;\">field terminator is defined as .<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-r<\/td>\n<td style=\"border: thin solid gray;\">row terminator is defined as .<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-T<\/td>\n<td style=\"border: thin solid gray;\">use a trusted connection.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-m<\/td>\n<td style=\"border: thin solid gray;\">max errors to allow.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-c<\/td>\n<td style=\"border: thin solid gray;\">perform operation using char data type.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-E<\/td>\n<td style=\"border: thin solid gray;\">use identity values in file.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-f<\/td>\n<td style=\"border: thin solid gray;\">use the specified format file.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-b<\/td>\n<td style=\"border: thin solid gray;\">z rows per batch before commit.<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\">-h<\/td>\n<td style=\"border: thin solid gray;\">specify advance hints to be use.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>The first example re-creates the table and imports the data.<\/p>\n<pre><span style=\"color: #008000;font-size:small;\">-- Select BSA database\r\nUSE BSA;\r\nGO\r\n\r\n-- Remove the table\r\nDROP TABLE [STAGE].[TBL_RANK];\r\nGO\r\n\r\n-- Table w\/o default fields\r\nCREATE TABLE [STAGE].[TBL_RANK]\r\n(\r\n    [RANK_ID] [int] IDENTITY(1,1) NOT NULL,\r\n    [RANK_DESC] [varchar](50) NOT NULL,\r\n    CONSTRAINT [PK_TBL_RANK] PRIMARY KEY CLUSTERED ([RANK_ID] ASC)\r\n) \r\nGO\r\n\r\n-- BCP - Import Comma Seperated Value File\r\nDECLARE @bcp_cmd VARCHAR(1000);\r\nSET @bcp_cmd = 'BCP BSA.STAGE.TBL_RANK IN \"C:\\TEST\\RANK1.CSV\" -T -F 2 -t, -r \\n -E -m 1 -c '\r\nPRINT @bcp_cmd\r\nEXEC master..xp_cmdshell @bcp_cmd\r\nGO \r\n<\/span><\/pre>\n<p><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-1611\" title=\"bcp-in-example1\" src=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example1.jpg\" alt=\"\" width=\"716\" height=\"319\" srcset=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example1.jpg 716w, https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example1-300x133.jpg 300w\" sizes=\"auto, (max-width: 716px) 100vw, 716px\" \/><\/a><\/p>\n<p>I am going to make the problem a little more difficult by adding the three fields that are defaults. How do we now import a file that has less columns than the table?<\/p>\n<pre><span style=\"color: #008000;font-size:small;\">-- Add orginal fields\r\nALTER TABLE [STAGE].[TBL_RANK] ADD\r\n\t[ROW_GUID] [uniqueidentifier] ROWGUIDCOL NULL,\r\n\t[MODIFIED_DTE] [datetime] NULL,\r\n\t[MODIFIED_NM] [varchar](20) NULL;\r\nGO\r\n\r\n-- Add orginal constraints\r\nALTER TABLE [STAGE].[TBL_RANK] ADD  CONSTRAINT [DF_TR_ROW_GUID]  DEFAULT (newsequentialid()) FOR [ROW_GUID]\r\nGO\r\n\r\nALTER TABLE [STAGE].[TBL_RANK] ADD  CONSTRAINT [DF_TR_MODIFIED_DTE]  DEFAULT (getdate()) FOR [MODIFIED_DTE]\r\nGO\r\n\r\nALTER TABLE [STAGE].[TBL_RANK] ADD  CONSTRAINT [DF_TR_MODIFIED_NM]  DEFAULT ('BSA - SYSTEM') FOR [MODIFIED_NM]\r\nGO \r\n<\/span><\/pre>\n<p>That is where format files come in handy. We are going to use the BCP utility to create a format file from the table definition. From there, I am going to modify it by removing unwanted source rows and defining target fields. Run the following from a DOS command shell. All files used in the examples can be found at the end of the article.<\/p>\n<pre><span style=\"color: #008000;font-size:small;\">rem\r\nrem Run from cmd shell, create non xml format file, copy to final target and edit.\r\nrem\r\n\r\nbcp BSA.RECENT.TBL_RANK format nul -T -n -f rank2-all.fmt\r\n\r\ncopy rank2-all.fmt rank2.fmt\r\n<\/span><\/pre>\n<p>Some arguements of interest are used in this example. The FIRSTROW and LASTROW are used to select a subset of the source data file. The BATCHSIZE allows the database engine to commit changes to disk. This is really important when the number of records increases to free up resources. Last but not least, the FORMATFILE allows our custom file definition to be used.<\/p>\n<pre><span style=\"color: #008000;font-size:small;\">-- Remove data from table\r\nTRUNCATE TABLE STAGE.TBL_RANK;\r\nGO\r\n\r\n-- BCP - Import Tab Delimited File\r\nDECLARE @bcp_cmd1 VARCHAR(1000);\r\nSET @bcp_cmd1 = 'BCP BSA.STAGE.TBL_RANK IN \"C:\\TEST\\RANK2.TAB\" -T -F2 -L9 -b2 -f \"C:\\TEST\\RANK2.FMT\"'\r\nPRINT @bcp_cmd1\r\nEXEC master..xp_cmdshell @bcp_cmd1\r\nGO \r\n<\/span><\/pre>\n<p><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignleft size-full wp-image-1614\" title=\"bcp-in-example2\" src=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example2.jpg\" alt=\"\" width=\"783\" height=\"396\" srcset=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example2.jpg 783w, https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example2-300x151.jpg 300w\" sizes=\"auto, (max-width: 783px) 100vw, 783px\" \/><\/a><\/p>\n<p>The last arguement that I want to introduce today allows triggers to be executed when BCP is executed. This is an easy way to move data from one table to another or from STAGE to RECENT schemas. The snipet below adds the trigger to the staging table and imports the data.<\/p>\n<pre><span style=\"color: #008000;font-size:small;\">-- Remove data from table\r\nTRUNCATE TABLE STAGE.TBL_RANK;\r\nGO\r\n\r\n-- Remove data from table\r\nTRUNCATE TABLE RECENT.TBL_RANK;\r\nGO\r\n\r\n-- Add trigger to staging table\r\nCREATE TRIGGER TRG_STAGE_2_RECENT\r\nON [STAGE].[TBL_RANK] FOR INSERT\r\nAS \r\n  INSERT INTO [RECENT].[TBL_RANK] (RANK_DESC)\r\n  SELECT i.RANK_DESC FROM inserted i\r\nGO\r\n\r\n-- BCP - Import Data with triggers\r\nDECLARE @bcp_cmd1 VARCHAR(1000);\r\nSET @bcp_cmd1 = 'BCP BSA.STAGE.TBL_RANK IN \"C:\\TEST\\RANK2.TAB\" -T -F2 -L9 -b2 -f \"C:\\TEST\\RANK2.FMT\" -h \"FIRE_TRIGGERS\"'\r\nPRINT @bcp_cmd1\r\nEXEC master..xp_cmdshell @bcp_cmd1\r\n<\/span><\/pre>\n<p><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1615\" title=\"bcp-in-example3\" src=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example3.jpg\" alt=\"\" width=\"548\" height=\"390\" srcset=\"https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example3.jpg 548w, https:\/\/craftydba.com\/wp-content\/uploads\/2012\/02\/bcp-in-example3-300x213.jpg 300w\" sizes=\"auto, (max-width: 548px) 100vw, 548px\" \/><\/a><\/p>\n<p>Importing data by using the BCP command line utility is the best choice for moving large amounts of data. There are many options that can be specified that change the behavior of the program. A format file can be used to skip columns or define additional mappings.<\/p>\n<p>Many ETL programs such as IWAY Data Migrator use a graphical interface to draw process flows. But under the covers, the core engine uses <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms162802.aspx\">BCP<\/a> or <a href=\"http:\/\/docs.oracle.com\/cd\/B28359_01\/server.111\/b28319\/ldr_concepts.htm\">SQL Loader<\/a>, a data file and format file to get the job done quickly.<\/p>\n<p>The BCP utility is a great choice for creating ETL processes. I will be exploring using the utility next time to export data.<\/p>\n<p>Files Used In Examples<\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"175\" align=\"left\">\n<tbody>\n<tr>\n<td style=\"border: thin solid gray; background-color: #dbdbdb;\">FILE NAME<\/td>\n<td style=\"border: thin solid gray; background-color: #dbdbdb;\">PURPOSE<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\"><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2011\/11\/rank1.csv.txt\">rank1.csv<\/a><\/td>\n<td style=\"border: thin solid gray;\">Scout Rank Data (CSV)<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\"><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2011\/11\/rank2.tab_.txt\">rank2.tab<\/a><\/td>\n<td style=\"border: thin solid gray;\">Scout Rank Data (TAB)<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\"><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2011\/11\/rank2.fmt_.txt\">rank2.fmt<\/a><\/td>\n<td style=\"border: thin solid gray;\">Modified format file<\/td>\n<\/tr>\n<tr>\n<td style=\"border: thin solid gray;\"><a href=\"https:\/\/craftydba.com\/wp-content\/uploads\/2011\/11\/rank2-all.fmt_.txt\">rank2-all.fmt<\/a><\/td>\n<td style=\"border: thin solid gray;\">BCP format file based on table<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>The BCP command line utility is the Cadillac of ETL programs for text based data files. It is REALLY FAST. It can perform both imports and exports and it can generate format files from existing objects. Today, I am going implement the same business algorithms I did earlier (Part 2) using the BCP program instead of BULK INSERT. We will be working again with the Boy Scouts of America (BSA) hypothetical database. I will be using the xp_cmdshell to execute BCP from a query window inside of SQL Server Management&hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[253,254,261,349,249,258,255,262,12,248,15,260,256,257,259,28,29],"class_list":["post-1584","post","type-post","status-publish","format-standard","hentry","category-db-dev","tag-backup-database","tag-backup-log","tag-batchsize","tag-bcp","tag-export","tag-fieldterminator","tag-firstrow","tag-formatfile","tag-free-code","tag-import","tag-john-f-miner-iii","tag-keepidentity","tag-lastrow","tag-maxerrors","tag-rowterminator","tag-sql-server","tag-tsql"],"_links":{"self":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/posts\/1584","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1584"}],"version-history":[{"count":0,"href":"https:\/\/craftydba.com\/index.php?rest_route=\/wp\/v2\/posts\/1584\/revisions"}],"wp:attachment":[{"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1584"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1584"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/craftydba.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1584"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}