SQL Server常见问题解析
前言
项目开发使用的数据库是sql server,以下是工作中经常出现一些问题点:
一、处理 SQL Server 事务日志满的问题
1. 确认事务日志已满
- 错误提示:通常出现
9002
错误(日志空间不足)。 - 检查日志使用情况:
查看DBCC SQLPERF(LOGSPACE);
Log Space Used (%)
是否接近 100%。
2. 立即释放日志空间
情况 1:数据库为完整/大容量日志恢复模式
-
执行事务日志备份:
BACKUP LOG [数据库名] TO DISK = N'路径\日志备份文件.trn';
备份后,日志空间会被标记为可重用。
-
若备份失败:
- 检查备份设备(磁盘空间、权限等)。
- 若紧急情况下需强制释放空间,可切换为简单恢复模式(谨慎操作,会打断日志链):
ALTER DATABASE [数据库名] SET RECOVERY SIMPLE; DBCC SHRINKFILE (N'日志逻辑文件名', 1); -- 收缩日志文件 ALTER DATABASE [数据库名] SET RECOVERY FULL; -- 恢复原模式
情况 2:数据库为简单恢复模式
- 触发检查点,使日志自动截断:
CHECKPOINT;
3. 收缩事务日志文件
- 收缩日志文件(仅在紧急时使用,避免频繁操作):
若收缩失败,需检查是否有活动事务占用日志空间。USE [数据库名]; DBCC SHRINKFILE (N'日志逻辑文件名', 目标大小_MB); -- 如 DBCC SHRINKFILE (N'MyDB_Log', 1024);
4. 检查并终止长时间运行的事务
- 查看未提交事务:
若存在长时间未提交的事务,需联系相关人员提交或终止:DBCC OPENTRAN;
KILL [会话ID]; -- 谨慎操作
5. 优化日志文件配置
- 调整日志初始大小和增长策略:
ALTER DATABASE [数据库名] MODIFY FILE ( NAME = N'日志逻辑文件名', SIZE = 初始大小_MB, -- 如 4096MB FILEGROWTH = 增长量_MB -- 如 1024MB,避免百分比增长 );
- 检查虚拟日志文件(VLF)碎片:
若存在大量 VLFs,需通过备份后收缩日志并调整增长量优化。DBCC LOGINFO;
6. 预防措施
- 定期备份事务日志:确保完整/大容量模式下的日志备份计划。
- 监控日志增长:设置警报监控日志使用率。
- 避免自动收缩:禁用自动收缩(
AUTO_SHRINK
),手动维护更可控。 - 优化事务设计:减少大事务,拆分批量操作。
紧急情况处理
- 磁盘空间不足:
- 扩展磁盘空间或移动日志文件到新磁盘:
需重启 SQL Server 服务生效。ALTER DATABASE [数据库名] MODIFY FILE ( NAME = N'日志逻辑文件名', FILENAME = N'新路径\日志文件.ldf' );
- 扩展磁盘空间或移动日志文件到新磁盘:
总结步骤
- 备份日志 → 2. 终止阻塞事务 → 3. 收缩日志 → 4. 调整日志配置 → 5. 设置监控与维护计划。
通过合理配置日志文件、定期备份及优化事务,可有效避免事务日志满的问题。
二、处理 System.Data.SqlClient版本太低
1.背景
使用sqlsugar的事务时,提示:
English Message : Connection open error . Enlisting in Ambient transactions is not supported.
Chinese Message : 连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,实在找不到原因请先Google错误信息:
Enlisting in Ambient transactions is not supported..
2.原因分析
默认的System.Data.SqlClient版本太低,导致Queryable查询的时候正常,插入Insertable的时候异常。
execute sp_lock;
3.解决办法
选择适合项目版本的System.Data.SqlClient进行升级即可。
三、处理 System.Data.SqlClient版本太低
1.背景
由于在设计时.备注总会在下方,需要下拉框才能看到字段的备注;
2.解决办法
1、关掉SQL server Management Studio,否则会被覆盖;
2、打开注册表路径: \HKEY_CURRENT_USER\Software\Microsoft\SQL Server Management Studio\18.0_IsoShell\DataProject;
3、把SSVPropViewColumnsSQL80和SSVPropViewColumnsSQL70的值修改为:"1,2,3,4,6,7,17;" 。
2.其他数值
1:Column Mame
2:Data Type
3:Length
4:Precision
5:Scale
6:Allow Nulls
7:Default value
11:Row GuID
12:Nullable
13:Condensed Type
14:Not for Replication
15:Formula
16:Collation
17:Description
四、Sqlserver高级语法
1.SQL INSERT INTO SELECT 语句
通过 SQL,您可以从一个表复制信息到另一个表。
INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。
SQL INSERT INTO SELECT 语句
INSERT INTO SELECT 语句从一个表复制数据,然后把数据插入到一个已存在的表中。目标表中任何已存在的行都不会受影响。
SQL INSERT INTO SELECT 语法
我们可以从一个表中复制所有的列插入到另一个已存在的表中:
INSERT INTO table2
SELECT * FROM table1;
或者我们可以只复制希望的列插入到另一个已存在的表中:
INSERT INTO table2
(column_name(s))
SELECT column_name(s)
FROM table1;
2.SQL SELECT INTO 语句
通过 SQL,您可以从一个表复制信息到另一个表。
SELECT INTO 语句从一个表复制数据,然后把数据插入到另一个新表中。
SQL SELECT INTO 语句
SELECT INTO 语句从一个表复制数据,然后把数据插入到另一个新表中。
注意:
MySQL 数据库不支持 SELECT ... INTO 语句,但支持 INSERT INTO ... SELECT 。
当然你可以使用以下语句来拷贝表结构及数据:
CREATE TABLE 新表
AS
SELECT * FROM 旧表
SQL SELECT INTO 语法
我们可以复制所有的列插入到新表中:
SELECT *
INTO newtable [IN externaldb]
FROM table1;
或者只复制希望的列插入到新表中:
SELECT column_name(s)
INTO newtable [IN externaldb]
FROM table1;
3.场景模拟一
原始数据库设计UserID为字符串类型,后续改完bigint,需做数据升级处理
----根据用户表更新结算主体的用户ID
update t set t.UserID=isnull(u.NewUserId,0) from ZJ_SettleAccount t
left join Base_Users u on u.UserID=t.UserID where t.UserID like 'uid%';
4.场景模拟二
数据库存在的2张表进行数据同步
----将明细信息同步到主表
insert into
Order_InsuranceMain(InsuranceMainID, Orderprice, InsurancPrice, OrderServiceID, InsuranceStatus, Description,MasterID, MerchantID, PolicyNo
,CreateID,CreateTime,ModifyID,ModifyTime,InsuranceType,OrderID
)
select InsuranceID,Orderprice, InsurancPrice, OrderServiceID, InsuranceStatus, Description,MasterID, MerchantID, PolicyNo,CreateID,
CreateTime,ModifyID,ModifyTime,InsuranceType,(select OrderID from Orders_Service where OrderServiceID=Order_Insurance.OrderServiceID) as OrderID
from
Order_Insurance where PolicyNo in(select distinct PolicyNo from Order_Insurance ) and Project='accidentinsurance_signin'
5.查看数据库中所有的视图
查看数据库中所有的视图
select
Name,--视图名字
Definition --视图内容
from sys.sql_modules AS m
inner join sys.all_objects as o on m.object_id = o.object_id
where o.[type] = 'v'