更改数据
前言:
在创建表并添加数据之后,更改或更新表中的数据就成为维护数据库的一个日常过程。Microsoft® SQL Server™ 提供下列方法更改现有表中的数据:
UPDATE 语?
可用来更新表或视图中特定行的数据。
数据库应用程序接口 (API)
支持用来更新某个结果集当前位置数据的选项。Transact-SQL 服务器游标也支持更新游标当前行的数据。
UPDATETEXT 语句
可用来更新特定的 ntext、text 和 image 值。
更新操作适用于视图和表,但是有一些限制条件。
1、使用 UPDATE 语句更改数据
UPDATE 语句可以更改表或视图中单行、行组或所有行的数据值。还可以用该语句更新远程服务器上的行(使用链接服务器名称或 OPENROWSET、OPENDATASOURCE 和 OPENQUERY 函数),前提是用来访问远程服务器的 OLE DB 提供程序支持更新操作。引用某个表或视图的 UPDATE 语句每次只能更改一个基表中的数据。
UPDATE 语句包括以下主要子句:
SET
包含要更新的列和每个列的新值的列表(用逗号分隔),格式为 column_name = expression。表达式提供的值包含多个项目,如常量、从其它表或视图的列中选择的值或使用复杂的表达式计算出来的值。
FROM
指定为 SET 子句中的表达式提供值的表或视图,以及各个源表或视图之间可选的联接条件。
WHERE
指定搜索条件,该搜索条件定义源表和视图中可以为 SET 子句中的表达式提供值的行。
此更新语句将类别 (category) 2 中所有 Northwind 产品的价格提高了 10%:
UPDATE Northwind.dbo.Products
SET UnitPrice = UnitPrice * 1.1
WHERE CategoryID = 2
使用 UPDATE 更改数据
Transact-SQL(点击查看)
说明 UPDATE 语句有日志记录;如果要更改大量的 text 或 image 数据,请考虑使用 UPDATETEXT 或 WRITETEXT 语句,这两个语句默认情况无日志记录。
使用 SET 子句更改数据
SET 子句指定要更改的列和这些列的新值。对所有符合 WHERE 子句搜索条件的行,将使用 SET 子句中指定的值更新指定列中的值。如果没有指定 WHERE 子句,则更新所有行。例如,如果 publishers 表中的所有出版社都将总部迁移到乔治亚 (Georgia) 州的亚特兰大 (Atlanta),则可使用以下 UPDATE 语句:
UPDATE publishers SET city = 'Atlanta', state = 'Georgia'
计算列的值可在更新操作中计算和使用。例如,要使 titles 表中的所有价格加倍,titles 表的 price 列可以设置为等于 price * 2。
SET 子句中使用的表达式也可以是只返回一个值的子查询;例如,如果 Northwind 数据库有一个 OrderSummary 表:
UPDATE OrderSummary
SET Last30Days =
(SELECT SUM(OrdDet.UnitPrice * OrdDet.Quantity)
FROM [Order Details] AS OrdDet
JOIN Orders AS Ord
ON (OrdDet.OrderID = Ord.OrderID
AND Ord.OrderDate DATEADD(dd,-30,GETDATE()) )
)
使用 WHERE 子句更改数据
WHERE 子句执行两种功能:
指定要更新的行。
如果同时指定了 FROM 子句,则指定源表中可以为更新语句提供值的行。
如果没有指定 WHERE 子句,则将更新表中的所有行。
以下 UPDATE 语句更改其中一个运输商的名称:
UPDATE Northwind.dbo.Shippers
SET CompanyName = 'United Shippers'
WHERE CompanyName = 'United Packages'
使用 FROM 子句更改数据
使用 FROM 子句可将数据从一个或多个表或视图拉入要更新的表中。例如,当作者 Dirk Stringer 获得一项合同,在 titles 表中为他的书 The Psychology of Computer Cooking 指定一个书名标识号时,就可以通过为这本最新的书添加书名标识号来更新 titleauthor 表中 Dirk 的行。
下例更新 titleauthor 表中 Dirk Stringer 的行,以便为作者最新的书添加书名标识号:
UPDATE titleauthor
SET title_id = titles.title_id
FROM titles INNER JOIN titleauthor
ON titles.title_id = titleauthor.title_id
INNER JOIN authors
ON titleauthor.au_id = authors.au_id
WHERE titles.title = 'Net Etiquette'
AND au_lname = 'Locksley'
2、使用游标更改数据
ADO、OLE DB 和 ODBC 应用程序接口 (API) 支持对结果集内应用程序所处的当前行进行更新。其基本过程如下:
将结果集的各列绑定到程序变量上。
执行查询。
执行 API 函数或方法,将应用程序定位在结果集的某一行上。
使用要更新的列的新数据值填充绑定的程序变量。
执行以下函数或方法之一插入行:
在 ADO 中,调用 Recordset 对象的 Update 方法。
在 OLE DB 中,调用 IRowsetChange 接口的 SetData 方法。
在 ODBC 中,调用带 SQL_UPDATE 选项的 SQLSetPos 函数。
使用 Transact-SQL 服务器游标时,可以使用包含 WHERE CURRENT OF 子句的 UPDATE 语句更新当前行。使用此子句所做的更改只影响游标所在行。如果游标基于某个联接,则只修改 UPDATE 语句中指定的 table_name。而不影响其它参与该游标的表。
USE Northwind
GO
DECLARE abc CURSOR FOR
SELECT CompanyName
FROM Shippers
OPEN abc
GO
FETCH NEXT FROM abc
GO
UPDATE Shippers SET CompanyName = N'Speedy Express, Inc.'
WHERE CURRENT OF abc
GO
CLOSE abc
DEALLOCATE abc
GO
3、更改 ntext、text 或 image 数据
有多种方法可以在替换整个值时更新行中的 ntext、text 或 image 值:
在 UPDATE 语句中指定相对较短的数据,其方式与 char、nchar 或 binary 数据相同。
使用 Transact-SQL WRITETEXT 语句。
ADO 应用程序可以使用 AppendChunk 方法指定较长的 ntext、text 或 image 数据。
OLE DB 应用程序可以使用 ISequentialStream 接口写入新的 ntext、text 或 image 值。
ODBC 应用程序可以使用 SQLPutData 的执行中的数据形式写入新的 ntext、text 或 image 值。
DB-Library 应用程序可以使用 dbwritetext 函数。
Microsoft® SQL Server™ 还支持仅更新 ntext、text 或 image 值的一部分。在 DB-Library 中,该操作可以使用 dbupdatetext 函数实现。
所有其它应用程序和 Transact-SQL 脚本、批处理、存储过程和触发器可以使用 UPDATETEXT 语句只更新 ntext、text 或 image 列的一部分。
以下脚本显示同时使用 UPDATETEXT 和 PATINDEX 查找和替换 text 值中特定字符串的方法:
USE Northwind
GO
CREATE TABLE TextParts (ColA INT PRIMARY KEY, ColB TEXT)
GO
INSERT INTO TextParts
VALUES( 1,
'Sample string START TAG Text to go END TAG Trailing text.')
GO
DECLARE @PtrVar BINARY(16)
DECLARE @InsertPos INT
DECLARE @DeleteLen INT
SELECT @PtrVar = TEXTPTR(ColB),
@InsertPos = (PATINDEX('%START TAG%', ColB) + 9),
@DeleteLen = (
PATINDEX('%END TAG%', ColB) -
( PATINDEX('%START TAG%', ColB) + 9
+ 2 /* allow for blanks */ )
)
FROM TextParts
WHERE ColA = 1
UPDATETEXT TextParts.ColB
@PtrVar
@InsertPos
@DeleteLen
WITH LOG
'The new text'
GO
SELECT * FROM TextParts
GO
由最后的 SELECT 语句得出的结果集为:
ColA ColB
----------- ------------------------------------------------------------
1 Sample string START TAG The new text END TAG Trailing text.