Skip to content

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+:支持 FILESTREAMMEMORY_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 [表名];

注意

  • TRUNCATEDELETE 快,但不能用于有外键约束的表
  • 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;

注意

  • REORGANIZEREBUILD 更快,但只适用于索引碎片率低于 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: 可以使用 EXECEXECUTE 命令执行存储过程:

  • 基本执行: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: 优化查询性能的方法包括:

  1. 为查询添加适当的索引
  2. 避免使用 SELECT *,只查询需要的列
  3. 使用参数化查询,避免 SQL 注入和提高查询计划重用率
  4. 避免在 WHERE 子句中使用函数
  5. 合理使用 JOIN 条件
  6. 考虑使用临时表或表变量存储中间结果

Q: 如何处理死锁?

A: 处理死锁的方法包括:

  1. 重新设计事务逻辑,避免循环依赖
  2. 缩短事务持有锁的时间
  3. 降低事务隔离级别(如使用 READ COMMITTED 而不是 SERIALIZABLE)
  4. 使用 SET DEADLOCK_PRIORITY 设置会话的死锁优先级
  5. 启用跟踪标志 1222 或 1204 来记录死锁信息
  6. 使用应用程序重试机制处理死锁

版本差异

SQL Server 2012+ 新特性

  1. OFFSET FETCH 分页:替代了 ROW_NUMBER() 进行分页查询
  2. THROW 语句:更强大的错误处理
  3. SEQUENCE 对象:生成序列数字
  4. FORMAT 函数:格式化日期和数字
  5. IIF 和 CHOOSE 函数:简化条件逻辑

SQL Server 2016+ 新特性

  1. JSON 支持:JSON 数据类型和相关函数
  2. DROP IF EXISTS:简化对象删除
  3. STRING_SPLIT 函数:拆分字符串
  4. TRUNCATE TABLE WITH PARTITIONS:截断指定分区
  5. TEMPORAL TABLES:系统版本化临时表

SQL Server 2019+ 新特性

  1. UTF-8 支持:原生 UTF-8 字符集支持
  2. BATCH_MODE_MEMORY_GRANT_FEEDBACK:智能内存授予
  3. APPROX_COUNT_DISTINCT:近似计数函数
  4. ACCELERATED_DATABASE_RECOVERY:加速数据库恢复
  5. MEMORY_OPTIMIZED_TEMPDB_METADATA:内存优化 TempDB 元数据

最佳实践

  1. 使用参数化查询:避免 SQL 注入,提高查询计划重用率
  2. 定期维护索引:重建或重新组织碎片率高的索引
  3. 使用适当的隔离级别:根据业务需求选择合适的隔离级别
  4. 实现错误处理:使用 TRY...CATCH 块处理异常
  5. 定期备份数据库:制定合理的备份策略
  6. 使用存储过程封装业务逻辑:提高安全性和性能
  7. 避免使用游标:尽量使用集合操作替代游标
  8. 使用适当的数据类型:选择合适的列数据类型
  9. 定期更新统计信息:确保查询优化器生成准确的查询计划
  10. 使用事务:确保数据一致性

总结

SQLServer 提供了丰富的命令和功能,用于数据库开发和管理。掌握这些常用命令对于开发人员和数据库管理员来说至关重要。在实际生产环境中,应根据具体需求选择合适的命令和语法,并遵循最佳实践,以确保数据库的性能、安全性和可靠性。

随着 SQLServer 版本的不断更新,新的命令和功能不断引入,开发人员应持续学习和掌握这些新特性,以提高开发效率和数据库性能。