The use of sqlserver cursor

During database development, when the data you are retrieving is just one record, the transaction statement code you write often uses the SELECT INSERT statement. But we often encounter such a situation, that is, read one record one by one from a certain result set. So how to solve this problem? Cursors provide us with an excellent solution.

1.1 Cursors and the advantages of cursors

    In the database, the cursor is a very important concept. Cursors provide a flexible means of manipulating data retrieved from a table. Essentially, a cursor is a mechanism for fetching one record at a time from a result set that includes multiple data records. A cursor is always associated with a T_SQL select statement because a cursor consists of a result set (which can be zero, one, or multiple records retrieved by the associated select statement) and a cursor position in the result set that points to a particular record. When you decide to process a result set, you must declare a cursor that points to the result set. If you've ever written a program in C to work with a file, a cursor is like the file handle you get when you open a file, and that file handle represents the file as long as the file is opened successfully. The same is true for cursors. It can be seen that the cursor can process the result set from the underlying table in a similar way to the traditional program reading a flat file, thereby presenting the data in the table to the program in the form of a flat file.

    We know that the relational database management system is set-oriented in nature, and there is no expression in MS SQL SERVER to describe a single record in a table, unless the where clause is used to limit only one record to be selected. Therefore, we must rely on the cursor to perform data processing oriented to a single record.

    It can be seen that the cursor allows the application to perform the same or different operations on each row in the row result set returned by the query statement select, instead of performing the same operation on the entire result set at one time; it also provides the data in the table based on the cursor position. The ability to delete or update; moreover, it is the cursor that links the database management system as a collection with the row-oriented programming and enables the two ways of handling data to communicate.

1.2 Types of cursors

MS SQL SERVER supports three types of cursors: Transact_SQL cursors , API server cursors and client cursors .

(1) Transact_SQL cursor

    Transact_SQL cursors are defined by the DECLARE CURSOR syntax and are mainly used in Transact_SQL scripts, stored procedures and triggers. Transact_SQL cursors are mainly used on the server and are managed by Transact_SQL statements sent from the client to the server or Transact_SQL in batches, stored procedures, and triggers. Transact_SQL cursors do not support fetching blocks or multiple rows of data.

(2) API cursor

    API cursors support the use of cursor functions in OLE DB, ODBC and DB_library, mainly on servers. Every time a client application calls an API cursor function, the MS SQL SEVER OLE DB provider, ODBC driver or DB_library dynamic link library (DLL) will pass these client requests to the server to process the API cursor.

(3) Client cursor

    Client cursors are primarily used when result sets are cached on the client. In client cursors, there is a default result set that is used to cache the entire result set on the client. Client cursors only support static cursors and not dynamic cursors. Because server cursors do not support all Transact-SQL statements or batches, client cursors are often used only as an auxiliary to server cursors. Because in general, the server cursor can support the vast majority of cursor operations.

    Because API cursors and Transact-SQL cursors are used on the server side, they are called server cursors, also known as background cursors, and client cursors are called foreground cursors. In this chapter we mainly talk about server (background) cursors.

select count(id) from info

select * from info

--Clear all records

truncate table info

declare @i int

set @i=1

while @i<1000000

begin

 insert into info values('Justin'+str(@i),'深圳'+str(@i))

 set @i=@i+1

end

1.3 Cursor Operations

There are four basic steps to use a cursor: declare the cursor , open the cursor , fetch data , and close the cursor .

declare cursor

As with other types of variables, a cursor should be declared before using it. The declaration of the cursor consists of two parts: the name of the cursor; the SQL statement used by the cursor. To declare a cursor called Cus-tomerCursor to query the name, account number and balance of a customer whose address is in Beijing, you can write the following code:

DECLARE CustomerCursor CURSOR FOR

SELECT acct_no,name,balance

FROM customer

WHERE province="北京";

One thing worth noting in the declaration of the cursor is that, like the declaration of other variables, the line of code that declares the cursor is not executed. You cannot set the breakpoint during debugging on this line of code, nor use IF...END IF statement to declare two cursors with the same name, such as the following code is wrong.

IF Is_prov="北京"THEN

DECLARE CustomerCursor CURSOR FOR

SELECT acct_no,name,balance

FROM customer

WHERE province="北京";

ELSE

DECLARE CustomerCursor CURSOR FOR

SELECT acct_no,name,balance

FROM customer

WHERE province〈〉"北京";

END IF

open cursor

After the cursor is declared, it must be opened before doing other operations. To open a cursor is to execute a SQL statement related to it. For example, to open a cursor declared in the above example, we only need to type:

OPEN CustomerCursor;

Since opening the cursor is to perform some SQL SELECT operations on the database, it will take a while, mainly depending on the system performance you use and the complexity of the statement. If the execution takes a long time, consider changing the mouse displayed on the screen to hourglass.

Extract data

When a cursor is opened with an OPEN statement and a query is executed in the database, you cannot immediately utilize the data in the query result set. You must use the FETCH statement to get the data . A FETCH statement can place one record at a time into a variable specified by the programmer . In fact, the FETCH statement is the core of cursor usage . In DataWindow and DataStore, after executing the Retrieve() function, all the results of the query can be obtained; while using the cursor, we can only get the query results one by one.

Having declared and opened a cursor, we can place data into arbitrary variables. In the FETCH statement you can specify the name of the cursor and the name of the target variable. For example:

FETCH CustmerCur-sor

INTO:ls_acct_no,

:ls_name,

:ll_balance;

Grammatically speaking, the above is a legal statement to fetch data, but generally we use cursors but should also include other parts. As we talked about earlier, the cursor can only fetch a record from the backend database at a time, and in most cases, what we want to do is to fetch from the first record in the database until the end. Therefore, we generally put the statement that the cursor extracts data into a loop until all the data in the result set is extracted, and then jump out of the loop . By detecting the value of SQLCA.SQL-CODE , you can know whether the last FETCH statement was successful. In general, when the SQLCODE value is 0, it means that everything is normal, 100 means that the end of the result set has been fetched, and other values ​​indicate that there is a problem , so we can write the following code:

lb_continue=True

ll_total=0

DO WHILE lb_continue

FETCH CustomerCur-sor

INTO:ls_acct_no,

:ls_name,

:ll_balance;

If sqlca.sqlcode=0 Then

ll_total+=ll_balance

Else

lb_continue=False

End If

LOOP

There are various structures of loop bodies, and the one mentioned here is the most common one. Some programmers also like to put a FETCH statement in front of the loop body, and then place another FETCH statement in the loop body, and check whether the SQLCA.SQLCODE is 100 (see the following example) . But doing so requires modifying two FETCH statements at the same time during maintenance, which is a little more troublesome.

close cursor

Please don't forget to close the cursor at the end of the cursor operation. This is a good programming practice, so that the system can release the resources occupied by the cursor. The statement to close the cursor is simple:

CLOSE CustomerCursor;

Use the Where clause

We can dynamically define the parameters of the Where clause in the cursor. For example, in this example, we directly define the records where the query province is Beijing, but maybe in the application we want to use a drop-down list box, and the user can select the records to be selected. What should we do with the province we inquired about?

As we mentioned earlier, the role of the DECLARE statement is only to define a cursor, and the cursor will actually be executed in the OPEN statement. Knowing this, we can easily implement such a function by adding variables as parameters to the Where clause of DECLARE, as shown below:

DECLARE CustomerCursor CURSOR FOR

SELCECT acct_no,name,balance

FROM customer

WHERE province=:ls_province;

// define the value of ls_province

OPEN CustomerCursor;

type of cursor

Like other variables, we can also define the access type of the cursor: global, shared, instance or local, and the naming conventions for cursor variables are the same as other variables.

-- declare cursor

declare my_cursor cursor keyset for select * from info

-- delete cursor resource

deallocate my_cursor

--Open the cursor, valid until the cursor is closed or deleted

open my_cursor

--Close the cursor

close my_cursor

--declare local variables

declare @id int,@name varchar(20),@address varchar(20)

--Locate the record at the specified location

fetch absolute 56488 from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--Locate to the relative position record of the current record

fetch relative -88 from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

-- Navigate to the previous record of the current record

fetch prior from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--Locate to the next record of the current record

fetch next from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--Locate to the first record

fetch first from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

--Locate to the end of the record

fetch last from my_cursor into @id,@name,@address

select @id as id,@name as name,@address as address

Example :

 use database1

declare my_cursor cursor scroll dynamic

 /**//* scroll means that the cursor pointer can be moved at will (otherwise only forward) , dynamic means that the cursor can be read and written (otherwise the cursor is read-only) */

for

select productname from  product

open my_cursor

declare @pname sysname

fetch next from my_cursor into @pname

while(@@fetch_status=0)

  begin

    print 'Product Name: ' + @pname

    fetch next from my_cursor into @pname

  end

fetch first from my_cursor into @pname

print @pname

/**//*update product set productname='zzg' where current of my_cursor */

/**//*delete from product where current of my_cursor */

close my_cursor

deallocate my_cursor

1.4 Advanced Techniques for Cursors

Although the languages ​​supported by the back-end databases based on SQL statements are roughly the same, there are some differences in the support for cursors, such as the support for scrolling cursors. The so-called scrolling cursor means that the programmer can specify the cursor to scroll forward or backward in any direction. As in Informix, you can even scroll the cursor to the beginning or end of the result set using the statements FETCH FIRST, FETCH LAST, FETCH PRIOR and FETCH NEXT. When the programmer uses the FETCH statement, it defaults to FETCH NEXT. Because scrolling is implemented in the background of the database, the scrolling cursor provides great convenience for user programming.

Another difference in cursor support is that of modifiable cursors. The use of the above cursors all refer to read-only cursors, while databases such as Oracle and Sybase also support cursors that can be modified. Using such a database, you can modify or delete the row on which the current cursor is located. For example, to modify the balance of the user in the row where the current cursor is located, we can do the following:

UPDATE customer

SET balance=1000

WHERE CURRENT OF customerCursor;

The operation to delete the current row is as follows:

DELETE FROM Customer

WHERE CURRENT OF CustomerCursor;

But if the database you are currently using is Sybase, you need to modify the parameters of the database and set the cursor modifiable value to 1 to perform the above operations. This assignment can be done before or after connecting to the database.

SQLCA.DBParm="Cursor Update=1"

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324670468&siteId=291194637