附注:微软认证考试70-461范围
- Create Database Objects创建数据库对象 (24%)
- Work with Data数据处理 (27%)
- Modify Data数据修改 (24%)
- Troubleshoot & Optimize故障排解及SQL优化 (25%)
本文是第三节Modify Data数据修改。
第二部分:Modify data by using INSERT, UPDATE, and DELETE statements. May include but not limited to: given a set of code with defaults, constraints, and triggers, determine the output of a set of DDL; know which SQL statements are best to solve common requirements; use output statement. 使用INSERT,UPDATE和DELETE语句更新数据。可能包含但不仅限于:根据给出的具有默认值,约束和触发器的一组语句判断DDL的OUTPUT值;了解并制定最好的SQL语句解决普通需求;使用OUTPUT子句。
INSERT子句
(
ID int identity(1,1),
Name varchar(100) default('Hui Li'),
Name2 as '计算列 '+Name,
RN rowversion,
Note varchar(100) NULL
)
@@ROWCOUNT
插入单行数据
插入多行数据
默认值列
Timestamp时间戳列不能指定值插入
计算列不能指定值插入
插入数据到标识列
insert into test(id,name)values(10,'test10')
SET IDENTITY_INSERT test OFF
使用NEWID()插入GUID到uniqueidentifier列
使用SELECT和EXECUTE插入他表数据
使用 TOP 限制从源表插入的数据
通过使用 OPENQUERY 函数向远程表插入数据
VALUES ('Environmental Impact', 'Engineering');
通过使用 OPENDATASOURCE 函数向远程表插入数据
'Data Source= <server_name>; Integrated Security=SSPI')
.AdventureWorks2012.HumanResources.Department (Name, GroupName)
VALUES (N'Standards and Methods', 'Quality Assurance');
将数据插入堆中并按最小方式记录日志
SET RECOVERY BULK_LOGGED;
GO
INSERT INTO....
GO
ALTER DATABASE AdventureWorks2012
SET RECOVERY FULL;
GO
将 OPENROWSET 函数与 BULK 一起使用来将数据大容量加载到表中
SELECT b.Name, b.GroupName
FROM OPENROWSET (
BULK 'C:\SQLFiles\DepartmentData.txt',
FORMATFILE = 'C:\SQLFiles\BulkloadFormatFile.xml',
ROWS_PER_BATCH = 15000)AS b ;
GO
使用 TABLOCK 提示指定锁定方法
INSERT INTO Production.Location WITH (XLOCK)(Name, CostRate, Availability)
VALUES ( N'Final Inventory', 15.00, 80.00);
GO
使用OUTPUT捕获 INSERT 语句的结果
INSERT INTO Test(Name,UI,Note)
OUTPUT inserted.ID,inserted.Name,inserted.Name2 INTO @TMP
VALUES('Microsoft Exam',NEWID(),'test note')
select * from @TMP
INSERT INTO Test(Name,UI,Note)
OUTPUT inserted.ID,inserted.Name,inserted.Name2
VALUES('Microsoft Exam',NEWID(),'test note')
UPDATE子句
更新 text、ntext 和 image 列
若要替换或修改大型 text、ntext 或 image 数据块,请使用 WRITETEXT 或 UPDATETEXT,而不使用 UPDATE 语句。
如果 UPDATE 语句在更新聚集键以及一个或者多个 text、 ntext 或 image 列时可以更改多个行,则对这些列的部分更新将作为替换所有值来执行。
更新大值数据类型
当 UPDATE 语句导致下列任一操作时,数据库引擎便会将部分更新转换为完整更新:
•更改分区视图或表的键列。
•修改多行并且还将非唯一的聚集索引的键更新为非常量值。
不能使用 .WRITE 子句更新 NULL 列或将 column_name 的值设置为 NULL。
对于 varbinary 和 varchar 数据类型,以字节为单位指定 @Offset 和 @Length;对于 nvarchar 数据类型,则以字符为单位进行指定。 已针对双字节字符集 (DBCS) 排序规则计算了适当的偏移量。
为了获得最佳性能,建议按照块区大小为 8040 字节倍数的方式插入或更新数据。
如果在 OUTPUT 子句中引用了由 .WRITE 子句修改的列,则该列的完整值(deleted.column_name 中的前像或 inserted.column_name 中的后像)都返回到表变量中的指定列。
若要针对其他字符或二进制数据类型获得相同的 .WRITE 功能,请使用 STUFF (Transact-SQL)。
锁定行为
基本UPDATE语句
使用 WHERE CURRENT OF 子句
SELECT a.BusinessEntityID
FROM HumanResources.EmployeePayHistory AS a
WHERE RateChangeDate <>
(SELECT MAX(RateChangeDate)
FROM HumanResources.EmployeePayHistory AS b
WHERE a.BusinessEntityID = b.BusinessEntityID) ;
OPEN complex_cursor;
FETCH FROM complex_cursor;
UPDATE HumanResources.EmployeePayHistory
SET PayFrequency = 2
WHERE CURRENT OF complex_cursor;
CLOSE complex_cursor;
DEALLOCATE complex_cursor;
使用OUTPUT
OUTPUT inserted.Name,deleted.Name
WHERE ID=1
更新大型对象数据类型
使用包含 .WRITE 的 UPDATE 来修改 nvarchar(max) 列中的数据
UPDATE Document SET DocumentSummary .WRITE (N'features',28,10)
使用包含 .WRITE 的 UPDATE 在 nvarchar(max) 列中添加和删除数据
UPDATE Document
SET DocumentSummary = N'替换NULL'
WHERE ...;
-- 再用.WRITE替换值。方法: 开始位置0,长度设为NULL
UPDATE Document
SET DocumentSummary .WRITE(N'新值',0,NULL)
WHERE ...;
-- 追加数据
-- 方法:开始位置设为 NULL,长度设为0.
UPDATE Document
SET DocumentSummary .WRITE (N'追加数据', NULL, 0)
WHERE ...;
-- 删除从指定位置开始的所有字符
-- 方法:值设为NULL,长度设为0.
UPDATE Document
SET DocumentSummary .WRITE (NULL, 56, 0)
WHERE ...;
从位置56开始的字符将被全部删除
-- 删除指定段数据.
UPDATE Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE ...;
从位9到21的数据将被删除
使用包含 OPENROWSET 的 UPDATE 修改 varbinary(max) 列
UPDATE Production.ProductPhoto SET ThumbNailPhoto = ( SELECT * FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB) AS x ) WHERE ProductPhotoID = 1;
使用 UPDATE 来修改 FILESTREAM 数据
UPDATE Archive.dbo.Records SET [Chart] = CAST('Xray 1' as varbinary(max)) WHERE [SerialNumber] = 2;
通过使用提示覆盖查询优化器的默认行为
指定表提示
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ...;
指定查询提示
以下示例在 UPDATE 语句中指定查询提示OPTIMIZE FOR (@variable)。 此提示指示查询优化器在编译和优化查询时对局部变量使用特定值。 仅在查询优化期间使用该值,在查询执行期间不使用该值。CREATE PROCEDURE Production.uspProductUpdate @Product nvarchar(25) AS SET NOCOUNT ON; UPDATE Production.Product SET ListPrice = ListPrice * 1.10 WHERE ProductNumber LIKE @Product OPTION (OPTIMIZE FOR (@Product = 'BK-%') ); GO -- Execute the stored procedure EXEC Production.uspProductUpdate 'BK-%';