Geetanjali College of M.Sc.(IT & CA) Sem-I Subject :- SQL SERVER 2000 Ch - 9. Managing and Manipulating Data Topics Importing and Exportin Data Using the bcp utility and BULK INSERT Statement Introduction to Cursor Fetching and Scrolling Controlling Cursor behavior Cursor Locking Importing and Exporting Data Importing data from an external source into an instance of SQL Server is likely to be the first step that you will perform once you set up your database. After data has been imported into your database, you can start working with that data by using Transact-SQL statements and other tools to view and modify the data. You might also find that you need to export that data out of the database. Importing data is the process of retrieving data from sources external to SQL Server (for example, an ASCII text file) and inserting it into SQL Server tables. Exporting data is the process of extracting data from an instance of SQL Server into some userspecified format (for example, copying the contents of a SQL Server table to a Microsoft Access database). Now, you will learn how to use the bcp command prompt utility to copy data to and from a SQL Server database and will learn how to use the BULK INSERT statement to import data from a data file to a database. bcp Utility bcp {dbtable | query} {in | out | queryout | format} datafile followed by one or more switches. In this syntax, dbtable is the database_name + owner + table_name|view_name (for example, Northwind.dbo.customers or "Northwind.dbo.customers"): database_name is the name of the database in which the specified table or view resides. If not specified, this is the default database for the user. owner is the name of the owner of the table or view. table_name | view_name is the name of the destination table or view when copying data in to SQL Server (in), and the source table when copying data from SQL Server (out). query is a Transact-SQL query that returns a resultset. queryout must also be specified when bulk-copying data from a query. in | out | queryout | format Specifies the direction of the bulk copy (in copies from a file in to the database table or view, out copies from the database table or view to a file). queryout must be specified when bulk-copying data from a query. format creates a format file based on the switch specified (-n, -c, -w, -V, or -N) and the table or view delimiters. If format is used, the -f option must be specified as well. data_file is the data file used when bulk-copying a table or view in to or out of SQL Server. All available Bulk-Copy Program switches are listed below -m The maximum errors to allow before stopping the transfer. The default is 10. [–m max_errors] -f The format file used to customize the load or unload data in a specific style. [-f format_file] -e The file to write error messages to. [-e err_file] -F The first row in the data file to start copying from when importing. The default is 1. [-F first_row] -L The last row in the data file to end copying with when importing. The default is 0, which indicates the last row in the file. [-L last_row] -b The number of rows to include in each committed batch. By default, all data rows in a file are copied in one batch. [-b batch_size] -n Prepared By : Hiren Ghediya M.Sc(IT & CA) / MATERIAL / SEM-1 / SQL / CH-9 Page : 1 of 7 Native (database) data type formats are to be used for the data. [-n] -c Character data type format is to be used for the data. In addition, \t (tab character) is used as the field separator, and \n (newline character) is used as the row terminator. [-c] -w Unicode data type format is to be used for the data. In addition, \t (tab character) is used as the field separator, and \n (newline character) is used as the row terminator. [-w] -N Use Unicode for character data and native format for all others. This can be used as an alternative to the –w switch. [-N] -V Use data type formats from earlier versions of SQL Server. [-V (60 | 65 | 70)] -q Tells BCP to use quoted identifiers when dealing with table and column names. [-q] -C If you are loading extended characters, this switch allows you to specify the code page of the data in the data file. [-C code_page] -t The terminating character(s) for fields. The default is the \t (tab character). [-t field_term] -r The terminating character(s) for rows. The default is the \n (newline character). [-r row_term] -i A file for redirecting input into BCP (the response file containing the responses to the command prompts). [-i input_file] -o The file for receiving redirected output from BCP. [-o output_file] -a The network packet size (in bytes) used to send to or receive from SQL Server. Can be between 4096 and 65535 bytes. The default size is 4096. [-a packet_size] -S The SQL Server name to connect to. Local is the default. [-S server_name | server_name\instance_name] -U The user account to log in as; this account must have sufficient privileges to carry out either a read or a write of the table. [-U login_id] -P The password associated with the user account. [-P password] -T Make a trusted connection to the SQL Server using the network user/security credentials instead of the login_id/password. [-T] -v Display the BCP version information. [-v] -R Use the regional format for currency, date, and time data as defined by the locale settings of the client computer. [-R] -k Override a column's default and enforce NULL values being loaded into the columns as part of the BCP operation. [-k] -E Use the identity values in the import file rather than generating new ones. [-E] -h Special "hints" to be used during the BCP operation. These include specifying the following: the sort order of the data file, the number of rows of data per batch, the number of kilobytes of data per batch, to acquire a table-level lock, to check constraints, and to fire insert triggers. [-h hint_type,..] Example The following bcp command copies data from the Publishers table in the Pubs database and into the Publishers.txt file: bcp pubs..publishers out publishers.txt -c -T You can also use the bcp command prompt utility to bulk copy data from the Publishers.txt file into the Publishers2 table in the Pubs database: bcp pubs..publishers2 in publishers.txt -c -T BULK INSERT Data can also be transferred into a SQL Server table from a data file by using the BULK INSERT statement. The BULK INSERT statement cannot bulk copy data from an instance of SQL Server to a data file, however. With the BULK INSERT statement, you can bulk copy data to an instance of SQL Server by using the functionality of the bcp utility in a Transact-SQL statement (rather than from the command prompt). Prepared By : Hiren Ghediya M.Sc(IT & CA) / MATERIAL / SEM-1 / SQL / CH-9 Page : 2 of 7 In order for the bcp utility and the BULK INSERT statement to insert data, the data file must be in row and column format. SQL Server can accept data in any ASCII or binary format as long as the terminators (characters used to separate columns and rows) can be described. The structure of the data file does not need to be identical to the structure of the SQL Server table, because bcp and BULK INSERT enable columns to be skipped or reordered during the bulk copy process. Data that is bulk copied into an instance of SQL Server is appended to any existing contents in a table. Data that is bulk copied from an instance of SQL Server to a data file overwrites the previous contents of the data file. You should keep in mind the following guidelines when you bulk copy data: If you are importing data, the destination table must already exist. If you are exporting to a file, bcp will create the file. The number of fields in the data file does not have to match the number of columns in the table or be in the same order. The data in the data file must be in character format or in a format that the bcp utility generated previously, such as native format. Each column in the table must be compatible with the field in the data file being copied. For example, it is not possible to copy an int field to a datetime column using native format bcp. Relevant permissions to bulk copy data are required for source and destination files and tables. To bulk copy data from a data file into a table, you must have INSERT and SELECT permissions for the table. To bulk copy a table or view to a data file, you must have SELECT permission for the table or view being bulk copied. BULK INSERT allows the bulk load of data into a database table via transact-SQL. The main difference between this statement and BCP is that BULK INSERT is for loads only (and is SQL code), whereas BCP is a bidirectional, command-line–based utility. The CODEPAGE option is used when you need to load extended characters (values greater than 127); this option allows you to specify one of the following values for char, varchar, and text datatypes: ACP : Convert from the ANSI/Microsoft Windows code page (ISO 1252) to the SQL Server code page. OEM : Convert from the system OEM code page to the SQL Server code page. This is the default. RAW : No conversion, which makes this the fastest option. <value> Specific code page number (for example, 850 for the 4.2x default code page). The DATAFILETYPE option allows the specification of the data character set: char : Data is in ASCII format. native Data : is in SQL Server native format. widechar : Data is in Unicode format. widenative : Data is native, except for the char, varchar, and text columns, which are stored as Unicode. Use Pubs BULK INSERT Publishers2 FROM 'c:\publishers.txt‘ WITH (DATAFILETYPE = 'CHAR') BULK INSERT northwind..customers FROM 'd:\customers.dat' WITH ( FORMATFILE = 'd:\customers.fmt' ) Cursor A Cursor is an entity that maps over a result set and establishes a position on a single row within the result set. After the cursor is positioned on a row, operations can be performed on that row or on a block of rows starting at that position. Cursor Process Associate a cursor with the result set of a Transact-SQL statement, and define characteristics of the cursor, such as whether the rows in the cursor can be updated. Execute the Transact-SQL statement to populate the cursor. Retrieve the rows in the cursor you want to see. The operation to retrieve one row or one block of rows from a cursor is called a fetch. Performing a series of fetches to retrieve rows in either a forward or backward direction is called scrolling. Optionally, perform modification operations (update or delete) on the row at the current position in the cursor. Close the cursor. Introduction to Cursors Operations in a relational database act on a complete set of rows. The set of rows returned by a SELECT statement consists of all the rows that satisfy the conditions in the WHERE clause of the statement. This complete set of rows returned by the statement is known as the RESULT SET. Applications-especially interactive, online applications-cannot always work effectively with the entire result set as a unit. Prepared By : Hiren Ghediya M.Sc(IT & CA) / MATERIAL / SEM-1 / SQL / CH-9 Page : 3 of 7 These applications need a mechanism to work with one row or with a small block of rows at a time. Cursors are an extension to result sets that provide that mechanism. Cursors extend result processing by supporting the following functionalities: Allowing positioning at specific rows of the result set Retrieving one row or block of rows from the current position in the result set Supporting data modifications to the rows at the current position in the result set Supporting different levels of visibility for changes made by other users to the data in the result set Providing access to the data in a result set for Transact-SQL statements in scripts, stored procedures, and triggers Types Of Cursors SQL Server supports three types of cursor implementations: Transact-SQL server cursors API server cursors, client cursors. Because Transact-SQL server cursors and API server cursors are implemented on the server, they are referred to collectively as server cursors. Do not mix the use of these various types of cursors. Transact-SQL cursors. It is based on the DECLARE CURSOR syntax and are used mainly in Transact-SQL scripts, stored procedures, and triggers. Transact-SQL cursors are implemented on the server and are managed by Transact-SQL statements sent from the client to the server. Application programming interface (API) server cursors It Supports the API cursor functions in OLE DB, ODBC and DB-Library. API server cursors are implemented on the server. Each time a client application calls an API cursor function, the SQL Server OLE DB provider, ODBC driver, or DB-Library dynamic-link library (DLL) transmits the request to the server for action against the API server cursor. Client cursors It is implemented internally by the SQL Server ODBC driver, the DB-Library DLL, and by the DLL that implements the ADO API. Client cursors are implemented by caching all the result set rows on the client. Each time a client application calls an API cursor function, the SQL Server ODBC driver, the DB-Library DLL, or the ADO DLL performs the cursor operation on the result set rows cached on the client. Transact-SQL Cursors Transact-SQL Server cursors are based on the DECLARE CURSOR statement and are used mainly in Transact-SQL scripts, stored procedures, and triggers. Transact- SQL cursors are implemented on the server and are managed by Transact-SQL statements sent from the client to the server. Steps for Cursor Use a DECLARE CURSOR statement to declare the cursor. When you declare the cursor, you should specify the SELECT statement that will produce the cursor's result set. Use an OPEN statement to populate the cursor. This statement executes the SELECT statement embedded in the DECLARE CURSOR statement. Use a FETCH statement to retrieve individual rows from the result set. Typically, a FETCH statement is executed many times (at least once for each row in the result set). If appropriate, use an UPDATE or DELETE statement to modify the row. This step is optional. Use a CLOSE statement to close the cursor. This process ends the active cursor operation and frees some resources (such as the cursor's result set and its locks on the current row). The cursor is still declared, so you can use an OPEN statement to reopen it. Use a DEALLOCATE statement to remove the cursor reference from the current session. This process completely frees all resources allocated to the cursor (including the cursor name). After a cursor is deallocated, you must issue a DECLARE statement to rebuild the cursor. DEALLOCATE AuthorsCursor 1. Declaring Cursors A cursor is declared for a SELECT statement Syntax DECLARE cursor_name CURSOR [LOCAL | GLOBAL] [FORWARD_ONLY | SCROLL] [STATIC | KEYSET | DYNAMIC] [READ_ONLY | SCROLL_LOCKS | OPTIMISTIC] FOR select_statement [FOR {READ ONLY | UPDATE [OF column_list]}] You cannot use COMPUTE, COMPUTE BY, FOR BROWSE, or INTO in the select_statement. Prepared By : Hiren Ghediya M.Sc(IT & CA) / MATERIAL / SEM-1 / SQL / CH-9 Page : 4 of 7 Local and Global Cursors Global cursors remain defined for a connection until they are explicitly deallocated, or until they are implicitly deallocated at termination of the connection. A local cursor's scope is limited to the batch, stored procedure, or trigger in which it is defined. The cursor is implicitly deallocated when the batch, stored procedure, or trigger terminates unless a reference to it is passed to a calling stored procedure, batch, and so on via a cursor variable. The cursor will then go out of scope when the last variable referring to it goes out of scope. STATIC and INSENSITIVE Cursors STATIC and INSENSITIVE cursors are pretty much the same thing. STATIC is the T-SQL style syntax, and INSENSITIVE is the ANSI-style syntax. Both are populated with a snapshot of the data at the time the cursor is opened. The data is stored in a work table in tempdb. Any inserts, updates, or deletions to the table(s) from which the data originated do not affect the rows in the cursor. The rows in the cursor are not affected by any inserts, updates, or deletes to the table(s) the data came from. STATIC and INSENSITIVE cursors are read-only and cannot be updated. A static or insensitive cursor is useful if you do not want to be disturbed by changes to the underlying data while you process the cursor data. The only real difference between STATIC and INSENSITIVE cursors is that fetches are Forward Only by default for INSENSITIVE cursors unless the SCROLL option is specified. STATIC cursors are scrollable by default. KEYSET Cursors For KEYSET cursors, a list of the key values for the rows meeting the SELECT statement criteria are put into a work table in tempdb instead of the entire resultset. The membership of a KEYSET cursor is still static; however, you will be able to see changes to any of the rows to which the KEYSET cursor points, even if the row is modified to no longer meet the original SELECT statement criteria. Only if a row is deleted will it disappear from the resultset. KEYSET cursors are scrollable. To build a keyset, KEYSET cursors require that a unique index exists on the underlying table(s). DYNAMIC Cursors With DYNAMIC cursors, the membership is not fixed, and rows that didn't exist when the cursor was opened can qualify for a subsequent fetch. Likewise, any qualifying rows that have been deleted will disappear from the resultset. Because the rows in the cursor have not been locked, the cursor will see changes made to the data rows. FORWARD_ONLY Cursors If no specific cursor type options are specified, FORWARD ONLY is the default. A FORWARD ONLY cursor is a dynamic cursor that can only fetch the next row in forward order. Rows cannot be revisited. FORWARD ONLY cursors are typically the fastest type of cursor, but they are still slower than a normal SELECT statement. 2. Opening Cursors When you open a cursor, the SELECT statement is initiated to begin populating the cursor. For cursors declared with the INSENSITIVE or STATIC option, OPEN creates and populates a work table in tempdb with the cursor resultset. For KEYSET cursors, a work table in tempdb is populated with the unique keys for each row in the cursor resultset. When you specify the OPEN command, the cursor will be positioned above the first row: open cursor_test you can check how many rows the resultset contains with the function @@CURSOR_ROWS. If the value is –1, the cursor is being populated asynchronously, as for a dynamic cursor or forward-only cursor. If you close a cursor and open it again, the SELECT statement is re-executed and the cursor starts over at the beginning of the resultset. For FORWARD-ONLY cursors, this is the only way to return to a previous row in the cursor. 3. Fetching Rows After the cursor is opened, it is time to start reading rows from your cursor, which you do with the FETCH command: Example : fetch from titles_curs into @ytd_sales, @price The default for FETCH is to get the next row from the cursor. If the number of variables specified in the FETCH statement does not match the number of columns in the cursor SELECT statement, you will get a runtime error. You will also get a runtime error if the variable datatype does not match the column datatype and SQL Server cannot perform an implicit datatype conversion. Scrollable Cursors If you declare the cursor with the SCROLL keyword, you can navigate as you want within the resultset. For a scrollable cursor, you use the FETCH statement to navigate forward, backward, or to an absolute row in the resultset. Prepared By : Hiren Ghediya M.Sc(IT & CA) / MATERIAL / SEM-1 / SQL / CH-9 Page : 5 of 7 Example declare leads_curs scroll cursor for select cust_id, est_sale, close_date, prob, from leads for read only open leads_curs sales_id, descr Syntax : FETCH [[NEXT|PRIOR|FIRST|LAST|ABSOLUTE n|RELATIVE n] FROM cursor_name [INTO @variable_name1, @variable_name2, ...] The default if you don't specify a navigational option is to fetch the next row. The keyword NEXT is optional. Examples : fetch prior from leads_curs into @cust_id, @est_sale, @close_date, @prob, @sales_id, @descr fetch first from leads_curs into @cust_id, @est_sale, @close_date, @prob, @sales_id, @descr fetch absolute 10 from leads_curs into @cust_id, @est_sale, @close_date, @prob, @sales_id, @descr Relative scrolling can be forward (positive values) or backward (negative values). fetch relative -5 from leads_curs into @cust_id, @est_sale, @close_date, @prob, @sales_id, @descr check @@fetch_status after fetch to varify new row position. Return Value : 1 The resultset has at least one row or is a dynamic cursor. Cursor assigned to the variable is open and has at least one row or is a dynamic cursor. Return Value : 0 Cursor resultset is empty. Cursor assigned to the variable is empty. Return Value : -1 Cursor is closed. Cursor assigned to the variable is closed. Return Value : -2 N/A. No valid cursor is assigned to the variable. Return Value : -3 Cursor does not exist. Cursor variable doesn't exist or has not had a cursor assigned to it. 4. Modifying Cursor Rows To update or delete the currently fetched row in a cursor resultset, SQL Server provides the WHERE CURRENT OF cursor_name clause, which you can use in UPDATE and DELETE statements: UPDATE table_name SET column = expression [, column = expression[, ...]] WHERE CURRENT OF cursor_name DELETE table_name WHERE CURRENT OF cursor_name To update or delete rows using the WHERE CURRENT OF clause, you need to declare the cursor as updateable. If the cursor definition includes a join and you plan to update only one table in the cursor, but need to access information in another, the cursor should be declared FOR UPDATE. You can use the SHARED keyword to indicate which tables you will only be reading from and which will be modified. In the following example, you need to access the publishers table to increase prices on titles published in Massachusetts, but no modifications will be made to the publishers table: declare tp cursor for select title_id, type, price from titles t, publishers p shared where t.pub_id = p.pub_id and state = "MA" for update of price 5. Closing the Cursor Close the cursor as soon as you don't need it anymore. Open cursors hold locks on the underlying tables and use valuable resources. close titles_curs You can reopen the cursor after it has been closed. The SELECT statement is executed again and the cursor is repopulated. 6. Deallocating Cursors When you are finished with the cursor definition, you deallocate it. You cannot declare a GLOBAL cursor, or LOCAL cursor within the same scope with the same name until you have deallocated the previous cursor: Prepared By : Hiren Ghediya M.Sc(IT & CA) / MATERIAL / SEM-1 / SQL / CH-9 Page : 6 of 7 DEALLOCATE titles_curs It is a good idea to deallocate a cursor when you no longer need it. The query plan is released from memory at that time, and it makes the structure of your code clearer. Fetching and Scrolling The operation to retrieve a row from a cursor is called a fetch. When working with Transact-SQL cursors, you can use FETCH statements to retrieve rows from a cursor's result set. A FETCH statement supports a number of options that enable you to retrieve specific rows: FETCH FIRST. Fetches the first row in the cursor FETCH NEXT. Fetches the row after the last row fetched FETCH PRIOR. Fetches the row before the last row fetched FETCH LAST.Fetches the last row in the cursor FETCH ABSOLUTE n. Fetches the nth row from the first row in the cursor if n is a positive integer. If n is a negative integer, the row that is n rows before the end of the cursor is fetched. If n is 0, no rows are fetched. FETCH RELATIVE n. Fetches the row that is n rows from the last row fetched. If n is positive, the row that is n rows after the last row fetched is fetched. If n is negative, the row that is n rows before the last row fetched is fetched. If n is 0, the same row is fetched again. When a cursor is opened, the current row position in the cursor is logically before the first row. Transact-SQL cursors are limited to fetching one row at a time. API server cursors support fetching blocks of rows with each fetch. A cursor that supports fetching multiple rows at a time is called a block cursor. Cursor Locking In SQL Server, the SELECT statement in a cursor definition is subject to the same transaction locking rules that apply to any other SELECT statement. In cursors, however, an additional set of scroll locks can be acquired based on the specification of a cursor concurrency level. The transaction locks acquired by any SELECT statement, including the SELECT statement in a cursor definition, are controlled by the following options: The transaction isolation level setting for the connection Any locking hints specified in the FROM clause These locks are held until the end of the current transaction for both cursors and independent SELECT statements. When SQL Server is running in autocommit mode, each individual SQL statement is a transaction, and the locks are freed when the statement finishes. If SQL Server is running in explicit or implicit transaction mode, then the locks are held until the transaction is either committed or rolled back. END OF Chapter – 9 : Managing and Manipulating Data BEST WISHES Prepared By : Hiren Ghediya M.Sc(IT & CA) / MATERIAL / SEM-1 / SQL / CH-9 Page : 7 of 7