转贴:Microsoft OLE DB Provider for SQL Server错误80040e37

问题原因:

把数据库备份还原到另一个服务器时,可能会产生孤立用户的问题;

解决办法:

步骤:1.把备份的数据库还原到新的数据库服务器中(

      1.1企业管理器-->1.2数据库(右键)-->1.3所有任务-->1.4还原数据库-->1.5常规/还原为数据库/写上你要的数据库名字xxxx/选中从设备/选择设备/添加(浏览找到你的数据库备份文件)/确定/确定/确定-->1.6选项-->1.7将数据库还原为f:/usr/xxxx.mdf一般存放在你sql安装的目录下如:d:/Program Files/Microsoft SQL Server/MSSQL/Data/xxxx.mdf-->1.8确定就ok了!!

     2. 查看你刚刚还原的数据库中的用户如:abc;

     3. 查看安全性下面的登陆用户中是否有:abc如果没有此时的abc就是一个孤立用户;

     4.打开查询分析器运行脚本

       use  数据库名

       go  

       DECLARE   @sid   BINARY(16)   
       SELECT    @sid=sid FROM sysusers WHERE name='abc' and   islogin=1
       exec      sp_addlogin  @loginame = 'abc',@sid = @sid 

     5.注意,应该是先还原,如果事先在sql的安全性--登录中已经

      创建abc这个登录,则先删除它,再执行上面的语句.同过上面的就能解决问题了!

======================================================================

总结:孤立用户疑难解答   
  把数据库备份还原到另一个服务器时,可能会遇到孤立用户的问题。下面的方案显示解决了这个问题:    
  通过执行sp_addlogin,把登录   janetl   改名为   dbo。  
  sp_addlogin  'janetl', 'dbo'      
  备份数据库。在本例中,备份  Northwind。   
  BACKUP  DATABASE   Northwind   
  TO  DISK = 'c:/mssql/backup/northwnd'      
  除去刚刚备份的数据库。     
  DROP   DATABASE   Northwind      
  除去登录。     
  sp_droplogin   'janetl'      
  还原备份的数据库。     
  RESTORE   DATABASE   Northwind   
  FROM   DISK   =   'c:/mssql/backup/northwnd'      
  janetl  登录不能访问  Northwind  数据库,除非允许 guest   登录。尽管   janetl   登录已经删除,
它仍然(作为一个孤立行)显示在   sysusers   表中:     
  USE   Northwind   
  SELECT   *   
  FROM   sysusers   
  WHERE   name   =   'janetl'     
  解决孤立用户问题        
  用   sp_addlogin 添加一个临时登录。为孤立用户指定安全标识符(SID)(从   sysusers)。     
  sp_addlogin @loginame = 'nancyd',@sid   =   0x32C864A70427D211B4DD00104B9E8A00       
  用   sp_dropalias   除去属于别名   SID   的临时别名。     
  sp_dropalias   'nancyd'       
  用   sp_dropuser   除去原始用户(即现在的孤立用户)。     
  sp_dropuser   'janetl'      
  用   sp_dropuser   除去原始登录。     
  sp_droplogin   'nancyd'

========================================

--孤立用户的产生演示       
  --创建一个测试的数据库   
  CREATE   DATABASE   DB_test   
  go       
  --创建一个登录   
  EXEC   sp_addlogin   'aa'       
  --设置登录   aa   的默认数据库为测试数据库   DB_test   
  EXEC   sp_defaultdb   'aa','DB_test'   
  go       
  --切换到测试数据库   
  USE   DB_test   
  go     
  --为登录   aa   在当前测试数据库中添加用户   
  EXEC   sp_grantdbaccess   'aa'   
  go     
  --至此,用户   aa   登录后,其默认的当前数据库就是   DB_test   
  --我们可以在查询分析器,使用用户   aa   登录一下,来验证我们的测试环境   
    
  --备份测试数据库,为下面的测试做准备   
  BACKUP   DATABASE   DB_test   TO   DISK='c:/DB_test.bak'   WITH   INIT   
  go       
  /*===================   产生孤立用户   ======================*/       
  --切换到   master   数据库   
  USE   master   
  go
    
  --删除测试数据库   
  DROP   DATABASE   DB_test   
  go      
  --删除登录   aa   
  EXEC   sp_droplogin   'aa'   
  go     
  /*===================   孤立用户表现形式1   ======================*/     
  --还原测试数据库   
  RESTORE   DATABASE   DB_test   FROM   DISK='c:/DB_test.bak'   
  go    
  --切换到测试数据库   
  USE   DB_test   
  go     
  --查看用户信息   
  select   name   from   sysusers   where   islogin=1     
  --我们会发现,虽然我们已经将登录   aa   删除了,但用户   aa   仍然存在于数据库中   
  --尝试一下,用   aa   登录,被告知登录失败   
  go     
  --再把删除的登录添加回去   
  EXEC   sp_addlogin   'aa'     
  --设置登录   aa   的默认数据库为测试数据库   DB_test   
  EXEC   sp_defaultdb   'aa','DB_test'     
  --再次登录,被告知无法打开默认数据库,登录失败   
  go      
  --于是把默认数据库改为   master   
  EXEC   sp_defaultdb   'aa','master'      
  --这次再登录,就可以登录了   
  go     
  --尝试切换到测试数据库   DB_test   
  USE   DB_test    
  --得到错误信息:   服务器用户   'aa'   不是数据库   'DB_test'   中的有效用户。   
  --看来用户   aa   与登录   aa   失去了联系   
  go      
  --尝试重新为登录   aa   添加用户   aa   
  EXEC   sp_grantdbaccess   'aa'      
  --得到错误信息:当前数据库中已存在用户或角色   'aa'。    
  --这次我们换个顺序,先建立登录,再恢复数据库,看能否使登录与用户自动建立回联系       
  --做这个测试之前,先清理测试环境,即做前面的<产生孤立用户>步骤,然后再开始测试     
  --先添加登录   
  EXEC   sp_addlogin   'aa'   
  go       
  --还原测试数据库   
  RESTORE   DATABASE   DB_test   FROM   DISK='c:/DB_test.bak'   
  go       
  --切换到测试数据库   
  USE   DB_test   
  go      
  --查看用户信息   
  select   name   from   sysusers   where   islogin=1       
  --我们会发现,用户   aa   存在于数据库中   
  --尝试一下,用   aa   登录,并切换到   DB_test   
  --结果是登录成功,访问   DB_test   出现和测试1一样的错误

 for SQL Server 错误 '80040e37'

对象名 'Dv_User' 无效。

/***.asp,行 *

先查看了一下数据库表,确实有这个表存在,而且程序中调用语句也没错.
重写了一下代码,结果还是一样.
怀疑不是程序的问题,于是看其他页面,发现所有的页面都有类似的问题,只要有调用到数据库的地方,都会出现错误.

判断是数据库出现了问题.数据库链接没错.
导入也没错.

go了一把,就解决了.

--把所有表的所有者改为DBO就不会了。
--执行下面语句,更改所有表的所有者为DBO
exec sp_msforeachtable "sp_changeobjectowner '?','dbo'"
<think>我们正在处理一个关于Microsoft OLE DB Provider for SQL Server错误,具体错误信息是“试图从数据库提取逻辑页时对象不匹配”。这个错误通常与数据库内部的一致性有关,可能涉及页面损坏或元数据问题。以下将逐步分析可能的原因并提供解决方案。 ### 错误分析 该错误错误代码通常为`80004005`或类似的通用错误)表明在从磁盘读取数据页时,SQL Server发现页面的实际内容与预期的元数据(如对象ID)不匹配。这可能是由于以下原因之一: 1. **数据库页面损坏**:物理存储介质问题、I/O子系统故障或SQL Server内部错误可能导致数据页损坏。 2. **元数据不一致**:系统表(如`sysindexes`)中记录的对象信息与实际数据页上的对象标识符不一致。 3. **硬件问题**:内存、磁盘或控制器故障可能导致数据在读取或写入过程中损坏。 4. **SQL Server版本或补丁问题**:某些已知的Bug可能导致此类错误,尤其是在未打补丁的版本中。 ### 解决方案 #### 1. 运行数据库一致性检查 使用DBCC CHECKDB命令检查并修复数据库一致性: ```sql DBCC CHECKDB ('YourDatabaseName') WITH NO_INFOMSGS, ALL_ERRORMSGS; ``` - 如果检查报告错误,根据错误严重性选择修复选项: - 尝试使用`REPAIR_REBUILD`(不会丢失数据): ```sql ALTER DATABASE YourDatabaseName SET SINGLE_USER; DBCC CHECKDB ('YourDatabaseName', REPAIR_REBUILD); ALTER DATABASE YourDatabaseName SET MULTI_USER; ``` - 如果问题严重,可能需要使用`REPAIR_ALLOW_DATA_LOSS`(可能导致数据丢失): ```sql -- 谨慎使用,建议先备份 ALTER DATABASE YourDatabaseName SET SINGLE_USER; DBCC CHECKDB ('YourDatabaseName', REPAIR_ALLOW_DATA_LOSS); ALTER DATABASE YourDatabaseName SET MULTI_USER; ``` #### 2. 检查硬件问题 - 运行Windows内存诊断工具检查内存。 - 检查磁盘健康状态(使用`chkdsk`或厂商工具)。 - 查看SQL Server错误日志和Windows事件日志,寻找I/O错误。 #### 3. 更新SQL Server 确保SQL Server实例已安装最新服务包和累积更新。某些旧版本存在已知的页面损坏Bug。 #### 4. 恢复备份 如果存在未损坏的备份,考虑恢复数据库: ```sql RESTORE DATABASE YourDatabaseName FROM DISK = 'C:\Backup\YourDatabase.bak' WITH REPLACE; ``` #### 5. 联系Microsoft支持 如果以上步骤无法解决,可能涉及更深层次的损坏,建议联系Microsoft支持并提供DBCC输出。 ### 预防措施 - **定期备份**:实施完整备份和日志备份策略。 - **一致性检查**:定期运行`DBCC CHECKDB`。 - **监控硬件**:使用工具监控硬件健康状况。 - **保持更新**:及时应用SQL Server补丁。 ### 引用说明 在解决数据库错误时,确保环境符合访问接口要求[^1],并注意连接配置的正确性[^2][^3]。 §§相关问题§§ 1. 如何预防SQL Server数据库页面损坏? 2. DBCC CHECKDB命令的详细参数和使用方法有哪些? 3. SQL Server常见错误80004005的其他原因及解决方法是什么?</think>### Microsoft OLE DB Provider for SQL Server 错误:逻辑页对象不匹配分析 #### 错误原因分析 此错误(通常伴随错误代码 `80004005`)表明 SQL Server 在读取数据页时,发现**页头存储的对象ID与实际数据对象不匹配**。可能原因包括: 1. **数据库损坏** - 存储介质故障(如磁盘坏道)导致数据页损坏 - 非正常关机或硬件故障中断写入过程 - 内存错误导致写入脏页(例如:$ \text{PageID} = 0\text{x}1234 $ 但实际指向错误对象) 2. **元数据不一致** - 系统表(如 `sysindexes`)与数据页的映射关系失效 - 索引碎片或统计信息过时导致优化器选择错误访问路径 3. **连接配置问题** - 连接字符串参数不兼容(如访问旧版本数据库时未指定兼容级别)[^2] - 网络传输中数据包校验失败(常见于高延迟网络环境) 4. **SQL Server Bug** - 特定版本未修复的存储引擎缺陷(需验证补丁版本)[^1] #### 解决方案步骤 1. **紧急修复数据库** ```sql -- 进入单用户模式 ALTER DATABASE [YourDB] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; -- 执行修复(根据损坏程度选择) DBCC CHECKDB ('YourDB', REPAIR_REBUILD); -- 轻度损坏 DBCC CHECKDB ('YourDB', REPAIR_ALLOW_DATA_LOSS); -- 严重损坏 -- 恢复多用户模式 ALTER DATABASE [YourDB] SET MULTI_USER; ``` > **警告**:`REPAIR_ALLOW_DATA_LOSS` 可能导致数据丢失,操作前务必备份。 2. **验证硬件与配置** - 运行硬件诊断:`chkdsk /f` 检查磁盘错误 - 更新存储驱动程序(特别是 RAID 控制器驱动) - 检查 SQL Server 错误日志(位于 `Program Files\Microsoft SQL Server\MSSQL\Log`) 3. **优化连接配置** 在连接字符串中添加关键参数: ```vb oConn.Open "Provider=sqloledb;Data Source=ServerName;Initial Catalog=DBName; Connect Timeout=30;OLE DB Services=-2;" [^2] ``` - `OLE DB Services=-2` 禁用连接池,排除复用连接导致的上下文错误 - 增加 `Connect Timeout` 避免网络超时[^3] 4. **补丁与版本验证** - 确认 SQL Server 已安装最新累积更新(CU) - 检查 OLEDB 驱动版本是否符合要求(需 ≥ 7.3.3.4.0)[^1] - 升级到支持的 .NET Framework 版本(至少 4.6.1) #### 预防措施 - **定期维护任务**: ```sql -- 每周执行 EXEC sp_updatestats; -- 更新统计信息 ALTER INDEX ALL ON [TableName] REORGANIZE; -- 重组索引 ``` - **启用页校验和**: ```sql ALTER DATABASE [YourDB] SET PAGE_VERIFY CHECKSUM; ``` - **备份策略**: - 每日完整备份 + 每小时日志备份 - 使用 `RESTORE VERIFYONLY` 验证备份完整性 > 若问题持续,收集以下信息联系 Microsoft 支持: > 1. `DBCC CHECKDB` 完整输出 > 2. SQL Server 错误日志片段 > 3. Windows 系统事件日志(事件 ID 832, 833) > 4. 硬件诊断报告[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值