外观
SQLServer 常用开发命令
数据库操作命令
创建数据库
语法:
sql
CREATE DATABASE [数据库名]
ON (
NAME = 数据库名称,
FILENAME = '数据文件路径',
SIZE = 初始大小,
MAXSIZE = 最大大小,
FILEGROWTH = 增长方式
)
LOG ON (
NAME = 日志名称,
FILENAME = '日志文件路径',
SIZE = 初始大小,
MAXSIZE = 最大大小,
FILEGROWTH = 增长方式
);示例:
sql
CREATE DATABASE TestDB
ON (
NAME = TestDB_Data,
FILENAME = 'D:\Data\TestDB.mdf',
SIZE = 8MB,
MAXSIZE = 1024MB,
FILEGROWTH = 64MB
)
LOG ON (
NAME = TestDB_Log,
FILENAME = 'D:\Log\TestDB.ldf',
SIZE = 4MB,
MAXSIZE = 512MB,
FILEGROWTH = 32MB
);版本差异:
- SQL Server 2016+:支持
CONTAINMENT = PARTIAL创建包含数据库 - SQL Server 2019+:支持
FILESTREAM和MEMORY_OPTIMIZED_DATA选项
查看数据库
查看所有数据库:
sql
-- 方法 1
SELECT name, database_id, create_date FROM sys.databases;
-- 方法 2
EXEC sp_databases;查看当前数据库信息:
sql
SELECT DB_NAME() AS CurrentDatabase;
-- 查看数据库文件信息
SELECT * FROM sys.database_files;查看数据库大小:
sql
EXEC sp_spaceused;修改数据库
添加数据文件:
sql
ALTER DATABASE TestDB
ADD FILE (
NAME = TestDB_Data2,
FILENAME = 'D:\Data\TestDB2.ndf',
SIZE = 8MB,
MAXSIZE = 512MB,
FILEGROWTH = 64MB
);修改数据库名称:
sql
ALTER DATABASE OldDBName MODIFY NAME = NewDBName;删除数据库
语法:
sql
DROP DATABASE [数据库名];示例:
sql
DROP DATABASE TestDB;注意:删除数据库是不可逆操作,生产环境中需谨慎执行。
备份数据库
完整备份:
sql
BACKUP DATABASE TestDB
TO DISK = 'D:\Backup\TestDB_Full.bak'
WITH INIT, COMPRESSION, CHECKSUM;差异备份:
sql
BACKUP DATABASE TestDB
TO DISK = 'D:\Backup\TestDB_Diff.bak'
WITH DIFFERENTIAL, COMPRESSION, CHECKSUM;事务日志备份:
sql
BACKUP LOG TestDB
TO DISK = 'D:\Backup\TestDB_Log.trn'
WITH COMPRESSION, CHECKSUM;恢复数据库
完整恢复:
sql
RESTORE DATABASE TestDB
FROM DISK = 'D:\Backup\TestDB_Full.bak'
WITH REPLACE, RECOVERY;带移动文件的恢复:
sql
RESTORE DATABASE TestDB
FROM DISK = 'D:\Backup\TestDB_Full.bak'
WITH
MOVE 'TestDB_Data' TO 'D:\NewData\TestDB.mdf',
MOVE 'TestDB_Log' TO 'D:\NewLog\TestDB.ldf',
RECOVERY;表操作命令
创建表
语法:
sql
CREATE TABLE [表名] (
列名1 数据类型 [约束],
列名2 数据类型 [约束],
...
[表级约束]
);示例:
sql
CREATE TABLE Products (
ProductId INT PRIMARY KEY IDENTITY(1,1),
ProductName NVARCHAR(100) NOT NULL,
CategoryId INT NOT NULL,
Price DECIMAL(10,2) NOT NULL,
CreatedDate DATETIME DEFAULT GETDATE(),
CONSTRAINT FK_Products_Categories FOREIGN KEY (CategoryId) REFERENCES Categories(CategoryId)
);查看表
查看所有表:
sql
-- 方法 1
SELECT name, object_id, create_date FROM sys.tables;
-- 方法 2
EXEC sp_tables @table_type = 'BASE TABLE';查看表结构:
sql
-- 方法 1
EXEC sp_columns 'Products';
-- 方法 2
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'Products';修改表
添加约束:
sql
ALTER TABLE Products
ADD CONSTRAINT UQ_ProductName UNIQUE (ProductName);修改表名:
sql
EXEC sp_rename 'OldTableName', 'NewTableName';删除表
语法:
sql
DROP TABLE [表名];示例:
sql
DROP TABLE TempTable;清空表数据
语法:
sql
-- 方法 1:使用 TRUNCATE(速度快,不记录日志,不可回滚)
TRUNCATE TABLE [表名];
-- 方法 2:使用 DELETE(速度慢,记录日志,可回滚)
DELETE FROM [表名];注意:
TRUNCATE比DELETE快,但不能用于有外键约束的表TRUNCATE会重置自增列
列操作命令
添加列
语法:
sql
ALTER TABLE [表名]
ADD [列名] 数据类型 [约束];示例:
sql
ALTER TABLE Products
ADD Description NVARCHAR(MAX) NULL;修改列
修改列数据类型:
sql
ALTER TABLE Products
ALTER COLUMN Description NVARCHAR(2000) NULL;添加默认值约束:
sql
ALTER TABLE Products
ADD CONSTRAINT DF_Products_Active DEFAULT 1 FOR Active;删除列
语法:
sql
ALTER TABLE [表名]
DROP COLUMN [列名];示例:
sql
ALTER TABLE Products
DROP COLUMN Description;重命名列
语法:
sql
EXEC sp_rename '[表名].[旧列名]', '[新列名]', 'COLUMN';示例:
sql
EXEC sp_rename 'Products.OldColumnName', 'NewColumnName', 'COLUMN';索引操作命令
创建索引
创建非聚集索引:
sql
CREATE INDEX IX_Products_CategoryId
ON Products(CategoryId);创建唯一索引:
sql
CREATE UNIQUE INDEX IX_Products_ProductName
ON Products(ProductName);创建包含列的索引:
sql
CREATE INDEX IX_Products_CategoryId_Include
ON Products(CategoryId)
INCLUDE (ProductName, Price);查看索引
查看表的所有索引:
sql
-- 方法 1
EXEC sp_helpindex 'Products';
-- 方法 2
SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID('Products');修改索引
禁用索引:
sql
ALTER INDEX IX_Products_CategoryId ON Products DISABLE;启用索引:
sql
ALTER INDEX IX_Products_CategoryId ON Products REBUILD;删除索引
语法:
sql
DROP INDEX [索引名] ON [表名];示例:
sql
DROP INDEX IX_Products_CategoryId ON Products;重建索引
重建单个索引:
sql
ALTER INDEX IX_Products_CategoryId ON Products REBUILD WITH (ONLINE = ON);重建表的所有索引:
sql
ALTER INDEX ALL ON Products REBUILD WITH (ONLINE = ON);版本差异:
- SQL Server 2016+:支持
RESUMABLE = ON选项,允许暂停和恢复索引重建
重新组织索引
语法:
sql
ALTER INDEX IX_Products_CategoryId ON Products REORGANIZE;注意:
REORGANIZE比REBUILD更快,但只适用于索引碎片率低于 30% 的情况REORGANIZE是在线操作,不会阻塞查询
数据操作命令
插入数据
插入单行数据:
sql
INSERT INTO Products (ProductName, CategoryId, Price)
VALUES ('New Product', 1, 99.99);插入多行数据:
sql
INSERT INTO Products (ProductName, CategoryId, Price)
VALUES
('Product 1', 1, 49.99),
('Product 2', 2, 79.99),
('Product 3', 1, 129.99);从另一个表插入数据:
sql
INSERT INTO Products (ProductName, CategoryId, Price)
SELECT ProductName, CategoryId, Price FROM OldProducts;更新数据
更新单行数据:
sql
UPDATE Products
SET Price = 109.99, UpdatedDate = GETDATE()
WHERE ProductId = 1;更新多行数据:
sql
UPDATE Products
SET Price = Price * 1.1
WHERE CategoryId = 1;删除数据
删除单行数据:
sql
DELETE FROM Products
WHERE ProductId = 1;删除多行数据:
sql
DELETE FROM Products
WHERE CategoryId = 3;查询数据
基本查询:
sql
SELECT ProductId, ProductName, Price
FROM Products
WHERE CategoryId = 1
ORDER BY Price DESC;分页查询:
sql
-- SQL Server 2005+:使用 ROW_NUMBER()
SELECT ProductId, ProductName, Price
FROM (
SELECT ProductId, ProductName, Price, ROW_NUMBER() OVER (ORDER BY ProductId) AS RowNum
FROM Products
) AS PagedProducts
WHERE RowNum BETWEEN 11 AND 20;
-- SQL Server 2012+:使用 OFFSET FETCH
SELECT ProductId, ProductName, Price
FROM Products
ORDER BY ProductId
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;存储过程操作命令
创建存储过程
语法:
sql
CREATE PROCEDURE [存储过程名]
@参数1 数据类型 [= 默认值],
@参数2 数据类型 [= 默认值]
AS
BEGIN
-- 存储过程逻辑
END;示例:
sql
CREATE PROCEDURE GetProductsByCategory
@CategoryId INT,
@MinPrice DECIMAL(10,2) = 0
AS
BEGIN
SET NOCOUNT ON;
SELECT ProductId, ProductName, Price
FROM Products
WHERE CategoryId = @CategoryId AND Price >= @MinPrice
ORDER BY Price;
END;查看存储过程
查看所有存储过程:
sql
SELECT name, object_id, create_date FROM sys.procedures;查看存储过程定义:
sql
-- 方法 1
EXEC sp_helptext 'GetProductsByCategory';
-- 方法 2(SQL Server 2012+)
SELECT OBJECT_DEFINITION(OBJECT_ID('GetProductsByCategory')) AS Definition;修改存储过程
语法:
sql
ALTER PROCEDURE [存储过程名]
@参数1 数据类型 [= 默认值],
@参数2 数据类型 [= 默认值]
AS
BEGIN
-- 修改后的逻辑
END;删除存储过程
语法:
sql
DROP PROCEDURE [存储过程名];示例:
sql
DROP PROCEDURE OldProcedure;执行存储过程
基本执行:
sql
EXEC GetProductsByCategory @CategoryId = 1;执行带多个参数的存储过程:
sql
EXEC GetProductsByCategory @CategoryId = 1, @MinPrice = 50.00;使用 OUTPUT 参数:
sql
CREATE PROCEDURE GetProductCount
@CategoryId INT,
@ProductCount INT OUTPUT
AS
BEGIN
SELECT @ProductCount = COUNT(*) FROM Products WHERE CategoryId = @CategoryId;
END;
-- 执行带 OUTPUT 参数的存储过程
DECLARE @Count INT;
EXEC GetProductCount @CategoryId = 1, @ProductCount = @Count OUTPUT;
SELECT @Count AS ProductCount;函数操作命令
创建标量函数
语法:
sql
CREATE FUNCTION [函数名](@参数 数据类型)
RETURNS 数据类型
AS
BEGIN
-- 函数逻辑
RETURN 结果;
END;示例:
sql
CREATE FUNCTION CalculateDiscount
(@Price DECIMAL(10,2), @DiscountPercent INT)
RETURNS DECIMAL(10,2)
AS
BEGIN
RETURN @Price * (1 - @DiscountPercent / 100.0);
END;创建表值函数
内联表值函数:
sql
CREATE FUNCTION GetProductsByPriceRange
(@MinPrice DECIMAL(10,2), @MaxPrice DECIMAL(10,2))
RETURNS TABLE
AS
RETURN
(
SELECT ProductId, ProductName, Price
FROM Products
WHERE Price BETWEEN @MinPrice AND @MaxPrice
);执行函数
执行标量函数:
sql
SELECT dbo.CalculateDiscount(99.99, 10) AS DiscountedPrice;执行表值函数:
sql
SELECT * FROM dbo.GetProductsByPriceRange(50.00, 200.00);删除函数
语法:
sql
DROP FUNCTION [函数名];示例:
sql
DROP FUNCTION CalculateDiscount;触发器操作命令
创建 DML 触发器
示例:
sql
CREATE TRIGGER TR_Products_Audit
ON Products
AFTER INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;
-- 记录删除操作
INSERT INTO ProductAudit (ActionType, ProductId, ProductName, Price, ActionDate)
SELECT 'DELETE', d.ProductId, d.ProductName, d.Price, GETDATE()
FROM deleted d;
-- 记录插入操作
INSERT INTO ProductAudit (ActionType, ProductId, ProductName, Price, ActionDate)
SELECT 'INSERT', i.ProductId, i.ProductName, i.Price, GETDATE()
FROM inserted i;
END;查看触发器
查看所有触发器:
sql
SELECT name, object_id, parent_id, create_date FROM sys.triggers;查看触发器定义:
sql
EXEC sp_helptext 'TR_Products_Audit';删除触发器
语法:
sql
DROP TRIGGER [触发器名];示例:
sql
DROP TRIGGER TR_Products_Audit;视图操作命令
创建视图
语法:
sql
CREATE VIEW [视图名]
AS
SELECT 列1, 列2, ...
FROM 表名
WHERE 条件;示例:
sql
CREATE VIEW vw_ProductInventory
AS
SELECT p.ProductId, p.ProductName, p.Price, i.Stock
FROM Products p
JOIN Inventory i ON p.ProductId = i.ProductId;查看视图
查看所有视图:
sql
SELECT name, object_id, create_date FROM sys.views;查看视图定义:
sql
EXEC sp_helptext 'vw_ProductInventory';修改视图
语法:
sql
ALTER VIEW [视图名]
AS
SELECT 列1, 列2, ...
FROM 表名
WHERE 条件;删除视图
语法:
sql
DROP VIEW [视图名];示例:
sql
DROP VIEW vw_OldView;事务操作命令
基本事务
语法:
sql
BEGIN TRANSACTION;
BEGIN TRY
-- 执行 SQL 语句
COMMIT TRANSACTION;
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
-- 处理错误
PRINT ERROR_MESSAGE();
END CATCH;示例:
sql
BEGIN TRANSACTION;
BEGIN TRY
UPDATE Products SET Price = 109.99 WHERE ProductId = 1;
INSERT INTO AuditLog (Action, TableName, RecordId, ActionDate)
VALUES ('UPDATE', 'Products', 1, GETDATE());
COMMIT TRANSACTION;
PRINT 'Transaction completed successfully.';
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION;
PRINT 'Transaction failed: ' + ERROR_MESSAGE();
END CATCH;设置事务隔离级别
语法:
sql
SET TRANSACTION ISOLATION LEVEL [隔离级别];隔离级别:
- READ UNCOMMITTED
- READ COMMITTED(默认)
- REPEATABLE READ
- SNAPSHOT
- SERIALIZABLE
示例:
sql
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
BEGIN TRANSACTION;
-- 事务逻辑
COMMIT TRANSACTION;权限操作命令
授予权限
语法:
sql
GRANT [权限] ON [对象] TO [用户/角色];示例:
sql
GRANT SELECT, INSERT, UPDATE ON Products TO UserName;拒绝权限
语法:
sql
DENY [权限] ON [对象] TO [用户/角色];示例:
sql
DENY DELETE ON Products TO UserName;撤销权限
语法:
sql
REVOKE [权限] ON [对象] FROM [用户/角色];示例:
sql
REVOKE UPDATE ON Products FROM UserName;查看权限
查看用户权限:
sql
EXEC sp_helprotect @username = 'UserName';系统命令
查看系统信息
查看 SQL Server 版本:
sql
SELECT @@VERSION;查看服务器名称:
sql
SELECT @@SERVERNAME;查看数据库状态
查看数据库状态:
sql
SELECT name, state_desc FROM sys.databases;查看数据库用户:
sql
SELECT name, type_desc FROM sys.database_principals WHERE type IN ('S', 'U');查看连接信息
查看当前连接:
sql
SELECT session_id, login_name, status, host_name, program_name, last_request_end_time
FROM sys.dm_exec_sessions WHERE is_user_process = 1;查看活动请求:
sql
SELECT * FROM sys.dm_exec_requests WHERE status = 'running';查看锁信息
查看当前锁:
sql
SELECT resource_type, resource_description, request_mode, request_status, request_session_id
FROM sys.dm_tran_locks;查看死锁信息
查看死锁事件:
sql
-- SQL Server 2012+
SELECT * FROM sys.dm_exec_requests WHERE session_id IN (
SELECT blocking_session_id FROM sys.dm_exec_requests WHERE blocking_session_id > 0
);查看最近的死锁图:
sql
-- 需要先启用跟踪标志 1222
DBCC TRACEON (1222, -1);
-- 查看错误日志中的死锁信息
EXEC xp_readerrorlog 0, 1, 'deadlock';常用查询命令
查询表结构
查看表的完整结构:
sql
EXEC sp_help 'Products';查看表的索引和约束:
sql
EXEC sp_helpconstraint 'Products';查询索引信息
查看索引使用情况:
sql
SELECT
OBJECT_NAME(i.object_id) AS TableName,
i.name AS IndexName,
i.type_desc AS IndexType,
us.user_seeks,
us.user_scans,
us.user_updates,
us.last_user_seek,
us.last_user_scan,
us.last_user_update
FROM sys.indexes i
LEFT JOIN sys.dm_db_index_usage_stats us
ON i.object_id = us.object_id AND i.index_id = us.index_id
WHERE OBJECTPROPERTY(i.object_id, 'IsUserTable') = 1;查询存储过程和函数定义
查询所有存储过程:
sql
SELECT name, object_id, create_date, modify_date
FROM sys.procedures ORDER BY modify_date DESC;查询所有函数:
sql
SELECT name, object_id, type_desc, create_date, modify_date
FROM sys.objects WHERE type IN ('FN', 'IF', 'TF') ORDER BY modify_date DESC;常见问题 (FAQ)
Q: 如何快速查看表结构?
A: 可以使用以下命令快速查看表结构:
EXEC sp_help 'TableName';- 查看表的完整信息,包括列、索引、约束等EXEC sp_columns 'TableName';- 查看表的列信息SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TableName';- 查看表的列信息
Q: 如何备份数据库?
A: 可以使用 BACKUP DATABASE 命令备份数据库,根据需求选择完整备份、差异备份或事务日志备份:
- 完整备份:
BACKUP DATABASE DBName TO DISK = 'BackupPath' WITH INIT, COMPRESSION; - 差异备份:
BACKUP DATABASE DBName TO DISK = 'BackupPath' WITH DIFFERENTIAL, COMPRESSION; - 事务日志备份:
BACKUP LOG DBName TO DISK = 'BackupPath' WITH COMPRESSION;
Q: 如何创建索引?
A: 可以使用 CREATE INDEX 命令创建索引,根据需求选择不同类型的索引:
- 非聚集索引:
CREATE INDEX IX_IndexName ON TableName(ColumnName); - 唯一索引:
CREATE UNIQUE INDEX UQ_IndexName ON TableName(ColumnName); - 包含列的索引:
CREATE INDEX IX_IndexName ON TableName(ColumnName) INCLUDE (Column1, Column2);
Q: 如何执行存储过程?
A: 可以使用 EXEC 或 EXECUTE 命令执行存储过程:
- 基本执行:
EXEC ProcedureName; - 带参数执行:
EXEC ProcedureName @Param1 = Value1, @Param2 = Value2; - 带输出参数执行:sql
DECLARE @OutputParam DataType; EXEC ProcedureName @InputParam = Value, @OutputParam = @OutputParam OUTPUT; SELECT @OutputParam AS Result;
Q: 如何查看锁信息?
A: 可以使用以下命令查看锁信息:
SELECT * FROM sys.dm_tran_locks;- 查看当前所有锁EXEC sp_lock;- 查看锁信息(已过时,但仍可用)SELECT * FROM sys.dm_exec_requests WHERE blocking_session_id > 0;- 查看阻塞会话
Q: 如何优化查询性能?
A: 优化查询性能的方法包括:
- 为查询添加适当的索引
- 避免使用
SELECT *,只查询需要的列 - 使用参数化查询,避免 SQL 注入和提高查询计划重用率
- 避免在 WHERE 子句中使用函数
- 合理使用 JOIN 条件
- 考虑使用临时表或表变量存储中间结果
Q: 如何处理死锁?
A: 处理死锁的方法包括:
- 重新设计事务逻辑,避免循环依赖
- 缩短事务持有锁的时间
- 降低事务隔离级别(如使用 READ COMMITTED 而不是 SERIALIZABLE)
- 使用
SET DEADLOCK_PRIORITY设置会话的死锁优先级 - 启用跟踪标志 1222 或 1204 来记录死锁信息
- 使用应用程序重试机制处理死锁
版本差异
SQL Server 2012+ 新特性
- OFFSET FETCH 分页:替代了 ROW_NUMBER() 进行分页查询
- THROW 语句:更强大的错误处理
- SEQUENCE 对象:生成序列数字
- FORMAT 函数:格式化日期和数字
- IIF 和 CHOOSE 函数:简化条件逻辑
SQL Server 2016+ 新特性
- JSON 支持:JSON 数据类型和相关函数
- DROP IF EXISTS:简化对象删除
- STRING_SPLIT 函数:拆分字符串
- TRUNCATE TABLE WITH PARTITIONS:截断指定分区
- TEMPORAL TABLES:系统版本化临时表
SQL Server 2019+ 新特性
- UTF-8 支持:原生 UTF-8 字符集支持
- BATCH_MODE_MEMORY_GRANT_FEEDBACK:智能内存授予
- APPROX_COUNT_DISTINCT:近似计数函数
- ACCELERATED_DATABASE_RECOVERY:加速数据库恢复
- MEMORY_OPTIMIZED_TEMPDB_METADATA:内存优化 TempDB 元数据
最佳实践
- 使用参数化查询:避免 SQL 注入,提高查询计划重用率
- 定期维护索引:重建或重新组织碎片率高的索引
- 使用适当的隔离级别:根据业务需求选择合适的隔离级别
- 实现错误处理:使用 TRY...CATCH 块处理异常
- 定期备份数据库:制定合理的备份策略
- 使用存储过程封装业务逻辑:提高安全性和性能
- 避免使用游标:尽量使用集合操作替代游标
- 使用适当的数据类型:选择合适的列数据类型
- 定期更新统计信息:确保查询优化器生成准确的查询计划
- 使用事务:确保数据一致性
总结
SQLServer 提供了丰富的命令和功能,用于数据库开发和管理。掌握这些常用命令对于开发人员和数据库管理员来说至关重要。在实际生产环境中,应根据具体需求选择合适的命令和语法,并遵循最佳实践,以确保数据库的性能、安全性和可靠性。
随着 SQLServer 版本的不断更新,新的命令和功能不断引入,开发人员应持续学习和掌握这些新特性,以提高开发效率和数据库性能。
