Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 50 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
50
Dung lượng
1,24 MB
Nội dung
CHAPTER 8 • ADVANCED TRANSACT-SQL
270
Committing a nested transaction does not write the changes from that transaction
permanently to the database; it merely makes them available to the outer transaction.
Suppose you have the following SQL batch:
BEGIN TRANSACTION
UPDATE titles
SET price = 20.00
WHERE title_id = ‘TC7777’
BEGIN TRANSACTION
UPDATE titles
SET type = ‘potboiler’
WHERE title_id = ‘TC7777’
COMMIT TRANSACTION
ROLLBACK TRANSACTION
In this case, the COMMIT TRANSACTION statement tells SQLServer that you’re
finished with the second transaction that you started. However, the ROLLBACK
TRANSACTION then rolls back all the work since the first BEGIN TRANSACTION,
including the inner nested transaction.
Although transaction names appear to offer increased readability for your code,
they interact poorly with nested transactions. In fact, you can refer to a transaction
by name only if it’s the outermost transaction in a batch. Our recommendation is to
avoid naming transactions if you plan to ever nest transactions.
COMMIT TRANSACTION
The syntax of COMMIT TRANSACTION is very similar to that of BEGIN TRANSAC-
TION. There’s also an alternative statement with the same purpose:
COMMIT TRANS[ACTION] [transaction_name | @name_variable]
COMMIT [WORK]
When you issue a COMMIT TRANSACTION statement, the most recent transaction
you started is marked as ready to commit. When you commit the outermost in a
series of nested transactions, the changes are written back to the database. Of course,
if there’s only one transaction open, the changes are written immediately.
It’s your responsibility to make sure you’ve made all the changes you want before
issuing a COMMIT TRANSACTION statement. Once a transaction has been commit-
ted, it can’t be rolled back.
Although you can use a name in the COMMIT TRANSACTION statement, SQL
Server makes no attempt to match this to a name in a BEGIN TRANSACTION state-
ment. The name’s purely for your convenience in making your code more readable.
2627ch08.qxt 8/22/00 10:41 AM Page 270
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
271
COMMIT, with or without the optional keyword WORK, is exactly synonymous to
COMMIT TRANSACTION with no transaction name. This form of the statement is
ANSI SQL-92 compatible.
ROLLBACK TRANSACTION
ROLLBACK TRANSACTION also comes in two forms:
ROLLBACK TRANS[ACTION]
[transaction_name |
@name_variable |
savepoint_name |
@savepoint_variable]
ROLLBACK [WORK]
ROLLBACK TRANSACTION throws away all changes since the most recent BEGIN
TRANSACTION. Again, you can supply a transaction name as either a constant or a
variable, but SQLServer ignores this name.
You can also roll back part of a transaction by supplying a savepoint name. We’ll
talk about savepoints in the next section. If a transaction is a distributed transaction
(one that affects databases on multiple servers), you can’t roll back to a savepoint.
ROLLBACK, with or without the optional WORK keyword, is the SQL-92 compli-
ant form of the statement. However, in this form, you can’t roll back only one of a set
of nested transactions. ROLLBACK WORK always rolls back to the outermost (first)
transaction in a batch.
WARNING ROLLBACK WORK rolls back all nested transactions and sets
@@TRANCOUNT to zero.
If you call ROLLBACK TRANSACTION as part of a trigger, subsequent SQL state-
ments in the same batch are not executed. On the other hand, if you call ROLLBACK
TRANSACTION in a stored procedure, subsequent SQL statements in the same batch
are executed.
SAVE TRANSACTION
The SAVE TRANSACTION statement lets you partially commit a transaction, while
still being able to roll back the rest of the transaction:
SAVE TRANS[ACTION] {savepoint_name | @savepoint_variable}
TRANSACTIONS
Transact-SQL
PART
II
2627ch08.qxt 8/22/00 10:41 AM Page 271
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ADVANCED TRANSACT-SQL
272
Note that when you issue SAVE TRANSACTION, you must name it. This name pro-
vides a reference point for a subsequent COMMIT TRANSACTION or ROLLBACK
TRANSACTION statement.
An example will make the use of SAVE TRANSACTION more clear. Consider the
following T-SQL batch:
BEGIN TRANSACTION
UPDATE titles
SET price = 20.00
WHERE title_id = ‘TC7777’
SAVE TRANSACTION pricesaved
UPDATE titles
SET type = ‘potboiler’
WHERE title_id = ‘TC7777’
ROLLBACK TRANSACTION pricesaved
COMMIT TRANSACTION
In this case, the ROLLBACK TRANSACTION statement removes the effects of the
update to the type column, while leaving the update to the price column ready to be
committed. Then the COMMIT TRANSACTION statement commits the part of the
transaction that wasn’t rolled back (in this case, the change to the price column).
@@TRANCOUNT
The @@TRANCOUNT system global variable tells you the number of nested transac-
tions that are currently pending. If no transactions are pending, this variable will con-
tain zero. This is useful for determining whether a trigger, for example, is executing in
the middle of a transaction already started by a T-SQL batch.
@@ERROR
The @@ERROR system global variable holds the most recent error number from any
T-SQL statement. Whenever a statement is executed that does not cause an error, this
variable will contain zero. That is, it’s reset to zero every time you successfully execute
a statement. So if you want to check at some later point whether a statement has
caused an error, you need to save the value of @@ERROR to a local variable.
A Transaction Example
Let’s end this section with a more complex T-SQL batch that will illustrate the
transaction-processing statements:
DECLARE @price_err int, @type_err int
BEGIN TRANSACTION
2627ch08.qxt 8/22/00 10:41 AM Page 272
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
273
UPDATE titles
SET price = 20.00
WHERE title_id = ‘TC7777’
SET @price_err = @@ERROR
SAVE TRANSACTION pricesaved
UPDATE titles
SET type = ‘potboiler’
WHERE title_id = ‘TC7777’
SET @type_err = @@ERROR
IF @type_err <> 0
ROLLBACK TRANSACTION pricesaved
IF @price_err = 0 AND @type_err = 0
BEGIN
COMMIT TRANSACTION
PRINT ‘Changes were successful’
END
ELSE
ROLLBACK TRANSACTION
Here’s a blow-by-blow account of this batch:
1. The DECLARE statement sets up two local variables.
2. The BEGIN TRANSACTION statement starts a transaction.
3. The first UPDATE statement makes a change to the price column.
4. The first SET statement is used to save the value of @@ERROR so that you can
check later whether the first UPDATE statement was successful. Note that this
statement must immediately follow the UPDATE statement.
5. The SAVE TRANSACTION statement sets a savepoint.
6. The second UPDATE statement makes a change to the type column.
7. The second SET statement is used to save the value of @@ERROR so you can tell
whether the second UPDATE statement succeeded.
8. If there was an error on the second UPDATE statement, the first ROLLBACK
TRANSACTION statement undoes the transaction back to the savepoint.
9. If there are no errors at all, the transaction is committed, and a message is
printed. Note the use of BEGIN and END to group two T-SQL statements into
one logical statement. This is necessary because the IF statement refers only to
the following statement.
TRANSACTIONS
Transact-SQL
PART
II
2627ch08.qxt 8/22/00 10:41 AM Page 273
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ADVANCED TRANSACT-SQL
274
10. If there are any errors, the second ROLLBACK TRANSACTION statement undoes
all of the work.
Distributed Transactions
So far, we’ve been discussing local transactions: those that make changes in a single
database. SQLServer also supports distributed transactions: transactions that make
changes to data stored in more than one database. These databases need not be SQL
Server databases; they can be databases on other linked servers.
NOTE For more information on linked servers, see Chapter 6.
A distributed transaction can be managed in code using exactly the same SQL
statements as you’d use for a local transaction. However, when you issue a COMMIT
TRANSACTION on a distributed transaction, SQLServer automatically invokes a pro-
tocol called two-phase commit (sometimes referred to as 2PC). In the first phase, SQL
Server asks every database involved to prepare the transaction. The individual data-
bases verify that they can commit the transaction and set aside all the resources nec-
essary to do so. It’s only if every involved database tells SQLServer that it’s OK to
commit the transaction that the second phase starts. In this phase, SQLServer tells
every involved database to commit the transaction. If any of the databases involved
are unable to commit the transaction, SQLServer tells all of the databases to roll back
the transaction instead.
Microsoft DTC
Distributed transactions are managed by a SQLServer component called the Distrib-
uted Transaction Coordinator (DTC). This is a separate service that’s installed at the
same time as SQL Server. If you’re going to use distributed transactions, you should
set this service to autostart. Figure 8.1 shows this service selected in the SQL Server
Service Manager.
2627ch08.qxt 8/22/00 10:41 AM Page 274
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
275
FIGURE 8.1
Checking the status of
the Microsoft DTC
service
BEGIN DISTRIBUTED TRANSACTION
You can tell SQLServer explicitly to start a distributed transaction with the BEGIN
DISTRIBUTED TRANSACTION statement:
BEGIN DISTRIBUTED TRANS[ACTION]
[transaction_name | @name_variable]
The only difference between this statement and the regular BEGIN TRANSACTION
statement is the inclusion of the DISTRIBUTED keyword.
Local transactions are automatically escalated to distributed transactions if you
change data on a remote server during the transaction. For example, if you execute an
INSERT, UPDATE, or DELETE statement on a remote server, or call a remote stored
procedure, while you’re in the midst of a transaction, that transaction will become a
distributed transaction.
Transaction Tips
Transactions consume resources on the server. In particular, when you change data
within a transaction, that data must be locked to ensure that it’s available if you com-
mit the transaction. So, in general, you need to make transactions efficient to avoid
causing problems for other users. Here are a few points to consider:
• Don’t do anything that requires user interaction within a transaction, because
this can cause locks to be held for a long time while the application is waiting
for the user.
• Don’t start transactions for a single SQL statement.
• Change as little data as possible when in a transaction.
TRANSACTIONS
Transact-SQL
PART
II
2627ch08.qxt 8/22/00 10:41 AM Page 275
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ADVANCED TRANSACT-SQL
276
• Don’t start a transaction while the user is browsing through data. Wait until
they’re actually ready to change the data.
• Keep transactions as short as possible.
Rowset Functions
Rowset functions are functions that return an object that can be used in place of a table
in another SQL statement. For example, as you saw in Chapter 7, some rowset func-
tions can be used to provide the rows to be inserted with an INSERT statement. There
are five rowset functions in SQLServer 2000:
• CONTAINSTABLE
• FREETEXTTABLE
• OPENQUERY
• OPENROWSET
• OPENDATASOURCE
CONTAINSTABLE
The CONTAINSTABLE statement lets you construct a virtual table from the results of a
complex full-text search. This statement’s syntax is a bit more complicated than that
of most of the statements we’ve examined so far:
CONTAINSTABLE (table_name, {column_name | *},
‘<search_condition>’ [,top_n])
<search_condition>::=
{
<generation_term> |
<prefix_term> |
<proximity_term> |
<simple_term> |
<weighted_term>
}
| {(<search_condition>)
{AND | AND NOT | OR}
<search_condition> […n]
}
2627ch08.qxt 8/22/00 10:41 AM Page 276
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
277
<generation_term> ::=
FORMSOF(INFLECTIONAL, <simple_term> [,…n])
<prefix_term> ::=
{“word*” | “phrase*”}
<proximity_term> ::=
{<simple_term> | <prefix_term> }
{{NEAR | ~} {<simple_term> | <prefix_term>}} […n]
<simple_term> ::=
word | “phrase”
<weighted_term> ::=
ISABOUT (
{{
<generation_term> |
<prefix_term> |
<proximity_term> |
<simple_term>
}
[WEIGHT (weight_value)]
} [,…n])
TIP You can use CONTAINSTABLE only on a table that’s been enabled for full-text
indexing. For more on full-text indexing, see Chapter 6.
If you work carefully through that syntax, you’ll see that the basic idea of CON-
TAINSTABLE is to allow you to do a “fuzzy” search, which returns items that might
not match entirely. Some further syntactical notes:
• Using the asterisk (*) to specify columns tells CONTAINSTABLE to search all
columns that have been registered for full-text searching, which might not be
all the columns in the table.
• Weight values are numbers between zero and one that specify how important
each match is considered to be in the final virtual table.
ROWSET FUNCTIONS
Transact-SQL
PART
II
2627ch08.qxt 8/22/00 10:41 AM Page 277
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
CHAPTER 8 • ADVANCED TRANSACT-SQL
278
• You can limit the number of results returned by specifying an integer in the
top_n parameter. This is useful when you’re searching a very large source table
and want to see only the most important matches.
The CONTAINSTABLE statement returns a virtual table containing two columns,
always named KEY and RANK. For example, consider the following statement:
SELECT * FROM
CONTAINSTABLE(Products, ProductName,
‘ISABOUT(mix WEIGHT(.8), sauce WEIGHT(.2))’)
Assuming that you’ve enabled the Product table in the Northwind sample database
for full-text searching on the ProductName column, this statement returns the results
shown in Figure 8.2. The ISABOUT search condition here specifies that results con-
taining the word mix should be rated as more important than those containing the
word sauce.
FIGURE 8.2
Using CONTAINSTABLE
to generate a
virtual table
The KEY column will always contain values from the column that you identified as
the primary key to the full-text indexing service. To make this statement more useful,
you’ll probably want to use this column to join back to the original table. Figure 8.3
shows the results of the following statement:
SELECT ProductName, RANK FROM
CONTAINSTABLE(Products, ProductName,
‘ISABOUT(mix WEIGHT(.8), sauce WEIGHT(.2))’)
2627ch08.qxt 8/22/00 10:41 AM Page 278
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
279
AS C
INNER JOIN Products
ON Products.ProductID = C.[KEY]
FIGURE 8.3
Using CONTAINSTABLE
joined to the original
search table
NOTE The virtual table needs to be aliased to be included in a join, and you must
include the square brackets around the joining name because KEY is a SQLServer keyword.
FREETEXTTABLE
Like CONTAINSTABLE, FREETEXTTABLE generates a virtual table based on full-text
indexing information. However, the syntax of FREETEXTTABLE is a good deal simpler:
FREETEXTTABLE (table_name, {column_name | *},
‘freetext’ [,top_n])
TIP You can use FREETEXTTABLE only on a table that’s been enabled for full-text
indexing. For more on full-text indexing, see Chapter 6.
ROWSET FUNCTIONS
Transact-SQL
PART
II
2627ch08.qxt 8/22/00 10:41 AM Page 279
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
[...]... creating linked servers, see Chapter 6 Figure 8.5 shows in SQLServer Enterprise Manager that the MOOCOW server knows about a linked server named BIGREDBARN, which is also a Microsoft SQLServer If you connected to the BIGREDBARN server directly, you could run a query like the following: SELECT * FROM Northwind.dbo.Customers PA R T II Transact -SQL FIGURE 8.5 Inspecting properties for a linked server This... you store a SQLServer view, the server creates an execution plan for that view The execution plan is a list of the steps that SQLServer will take to get the results of the view This plan is based on statistical information that the server maintains about things such as the number of rows in each table, the number of unique indexes in each table, and so on Based on this information, SQLServer decides... CHAPTER 8 • ADVANCED TRANSACT -SQL • Retrieving metadata • Using optimizer hints At this point, you should know enough T -SQL to handle most of your querying needs Now it’s time to look at SQLServer from a different standpoint, by considering the objects that SQLServer stores rather than the data that those objects hold In the next chapter, we’ll start with a look at SQLServer Enterprise Manager Please... BIGREDBARN server has been incorporated as one of the parameters of the OPENQUERY statement OPENQUERY is the easiest tool that you can use to perform distributed queries using SQLServer By using OPENQUERY, you can join any number of tables from different data sources These data sources don’t even need to be SQLServer tables; as long as they’re data sources that you can represent as linked servers (basically,... it won’t reflect the actual number of rows in the cursor That’s because SQLServer might decide to fetch data into the cursor asynchronously, so that processing can continue while the cursor is still being populated SQL Server will fill a cursor asynchronously if the cursor is declared with the STATIC or KEYSET parameters and SQL Server estimates that the number of rows will be greater than a certain... the exact syntax SQL Server uses for full-text searches Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark 2627ch08.qxt 8/22/00 10:41 AM Page 281 ROWSET FUNCTIONS 281 OPENQUERY The OPENQUERY statement lets you use any query (SQL statement that returns rows) on a linked server to return a virtual table The syntax of OPENQUERY is as follows: OPENQUERY(linked _server, ‘query’)... • If the cursor was declared with SQL- 92 syntax without SCROLL, only NEXT is supported • If the cursor was declared with SQL- 92 syntax with SCROLL, all options are supported • If the cursor was declared with SQL Server syntax with FORWARD_ONLY or FAST_FORWARD, only NEXT is supported Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Transact -SQL 2627ch08.qxt 2627ch08.qxt 290... to remove this watermark Transact -SQL 2627ch08.qxt 2627ch08.qxt 290 8/22/00 10:41 AM Page 290 CHAPTER 8 • ADVANCED TRANSACT -SQL • If the cursor was declared with SQLServer syntax with DYNAMIC SCROLL, all options except ABSOLUTE are supported • If the cursor was declared with SQLServer syntax and doesn’t fall into one of the above two categories, all options are supported The @@FETCH_STATUS global variable... T -SQL statements? You can refer to Figure 8.9 to confirm your results Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark Transact -SQL 2627ch08.qxt 2627ch08.qxt 294 8/22/00 10:41 AM Page 294 CHAPTER 8 • ADVANCED TRANSACT -SQL FIGURE 8.9 Running a batch in SQL Query Analyzer NOTE If you’re working with a client data-access library such as ADO, you may never need to deal with SQL. .. system tables are a set of tables that SQLServer uses to track information about users, databases, tables, replication tasks, and so on If SQLServer knows about a piece of information, it’s more than likely stored in a system table System tables break down into seven groups: • The master database contains a set of tables with information on databases, logins, servers, and other systemwide information . creating linked servers, see Chapter 6.
Figure 8.5 shows in SQL Server Enterprise Manager that the MOOCOW server
knows about a linked server named BIGREDBARN,. every involved database tells SQL Server that it’s OK to
commit the transaction that the second phase starts. In this phase, SQL Server tells
every involved