Sql server在使用sp_executesql @sql执行文本sql时,报错: Could not find database ID 16, name '16'. The database may be offline. Wait a few minutes and try again.
最近在公司项目中使用exec sp_executesql @sql执行一段文本sql的时候老是报错: Could not find database ID 16, name '16'. The database may be offline. Wait a few minutes and try again.执行的sql大概如下,注意其中有个额外的参数@databaseName是nvarchar类型,用来声明数据库的名字:
SET @tableScript=N''+
N'IF (SELECT COUNT(1) FROM ['+@databaseName+N'].dbo.sysobjects WHERE ID = OBJECT_ID(''['+@databaseName+N'].[dbo].[Raw_Tables_Metadata]''))=0
BEGIN
CREATE TABLE ['+@databaseName+N'].[dbo].[Raw_Tables_Metadata](
ID INT IDENTITY(1,1) NOT NULL,
Table_Name NVARCHAR(100) NOT NULL,
Column_Name NVARCHAR(100) NOT NULL,
Column_Type NVARCHAR(100) NOT NULL,
Column_Size NVARCHAR(100) NULL,
Skip_Rows INT NULL,
CONSTRAINT [PK_Raw_Tables_Metadata] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END'
EXEC sp_executesql @tableScript;
后来我查找了master.dbo.sysdatabases这个系统表:
select * from master.dbo.sysdatabases
发现dbid为16的数据库现在在sql server中不存在。我就纳闷了,明明我在上面sql文本中的参数@databaseName中声明的是数据库'A',执行上面语句后,为啥现在sql server报错说一个不存在的数据库id是offline的。。。后来在网上查了查,发现这有可能是因为sp_executesql这个执行sql文本的系统存储过程会复用缓存的执行计划。我才想起数据库'A'在sql server中前几天被删除重建过,在删除前'A'的dbid是16,而重建后数据库'A'的dbid不是16了,现在dbid为16的数据库在sql server中不存在。。。然而由于sql server中缓存的执行计划没有被更新,所以执行上面语句后,sql server还是会复用老的执行计划,去通过dbid=16来查找数据库'A',最后导致报错。
后来我将上面的语句做了下小小的改动,仅仅是在exec sp_executesql @sql的后面加上了with recompile关键字,如下所示:
SET @tableScript=N''+
N'IF (SELECT COUNT(1) FROM ['+@databaseName+N'].dbo.sysobjects WHERE ID = OBJECT_ID(''['+@databaseName+N'].[dbo].[Raw_Tables_Metadata]''))=0
BEGIN
CREATE TABLE ['+@databaseName+N'].[dbo].[Raw_Tables_Metadata](
ID INT IDENTITY(1,1) NOT NULL,
Table_Name NVARCHAR(100) NOT NULL,
Column_Name NVARCHAR(100) NOT NULL,
Column_Type NVARCHAR(100) NOT NULL,
Column_Size NVARCHAR(100) NULL,
Skip_Rows INT NULL,
CONSTRAINT [PK_Raw_Tables_Metadata] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END'
EXEC sp_executesql @tableScript with recompile;
加上with recompile后,exec sp_executesql @sql就不会重用系统中缓存的执行计划了,每次都是重新生成执行计划。不过这样做性能肯定是要低一些,但是至少保证了在我说的这个场景下不会出错。
所以在使用exec sp_executesql @sql的时候要小心,考虑缓存的执行计划被重用的可能性,另外可以参考下面这篇文章了解sp_executesql的执行计划缓存机制:
另外也有人建议使用DBCC FREEPROCCACHE清除sql server中所有缓存的执行计划来解决本文所述的问题(下面链接文章),但是DBCC FREEPROCCACHE这个语句对生产环境数据库的性能影响极大,不建议轻易使用!
http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=89821
Sql server在使用sp_executesql @sql执行文本sql时,报错: Could not find database ID 16, name '16'. The database may be offline. Wait a few minutes and try again.的更多相关文章
- 在sql server中怎样获得正在执行的Sql查询
方法1:使用DBCC inputbuffer(spid) 使用SP_WHO获得SPID,然后再执行上面的DBCC command,参见下图 执行一段sql语句 打开另一个query窗口并执行SP_WH ...
- sql server 2008 R2无法连接127.0.0.1报错 Server error:40(错误:53)
在公司用sql server 2008 R2很好的,回家连接127.0.0.1就报错.sql server2008R2主机名和.都可以登录,连接127.0.0.1出错,在与 SQL Server 建立 ...
- CentOS 7在执行yum操作时 报错
CentOS 7在执行yum操作时, 报错:Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=6&arch ...
- 在caffe中执行脚本文件时 报错:-bash: ./train.sh: Permission denied
报错原因:没有权限 解决方法:chmod 777 train.sh获得权限
- 优化SQL Server的内存占用之执行缓存
在论坛上常见有朋友抱怨,说SQL Server太吃内存了.这里笔者根据经验简单介绍一下内存相关的调优知识 首先说明一下SQL Server内存占用由哪几部分组成.SQL Server占用的内存主要 ...
- ms sql server 在cmd中执行sqlcmd的时候报错
cmd下直接输入sqlcmd会提示 错误: HResult 0x2,级别 16,状态 1命名管道提供程序: 无法打开与 SQL Server 的连接 [2].Sqlcmd: 错误: Microsoft ...
- Sql Server 带参数的存储过程执行方法
Sql Server 带参数的存储过程执行方法 Visual C# 动态操作 SQL Server 数据库实例教程(4):带参数的存储过程执行方法 上一篇文章介绍了带参数的SQL语句执行方法和不带参数 ...
- SQL Server游标 C# DataTable.Select() 筛选数据 什么是SQL游标? SQL Server数据类型转换方法 LinQ是什么? SQL Server 分页方法汇总
SQL Server游标 转载自:http://www.cnblogs.com/knowledgesea/p/3699851.html. 什么是游标 结果集,结果集就是select查询之后返回的所 ...
- SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型
原文:SQL Server 2008空间数据应用系列三:SQL Server 2008空间数据类型 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server ...
随机推荐
- JAVA+SELENIUM+MAVEN+TESTNG框架(二)新建项目
1.新建maven项目 2.下载selenium的jar包,放入maven依赖库中 3.新增testng依赖库,build path->add libirary->testng 4.查看自 ...
- 页面打印pdf格式文件
'<td><button type="button" class="btn btn-primary" data-loading-text=&q ...
- curl常用命令【转】
原文地址: http://www.thegeekstuff.com/2012/04/curl-examples/ 下载单个文件,默认将输出打印到标准输出中(STDOUT)中 curl http://w ...
- ibatis in的用法
<dynamic-mapped-statement name="queryLabelservicecodeLogSize" result-class="java.l ...
- 利用https实现站点的访问
简介 它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作,并返回网络上传送回的结果.HTTPS实际上应用了Netscape的安 全套接字层(SSL)作为HTTP应用层的子层.( ...
- Redis发布订阅机制
1. 什么是Redis Redis是一个开源的内存数据库,它以键值对的形式存储数据.由于数据存储在内存中,因此Redis的速度很快,但是每次重启Redis服务时,其中的数据也会丢失,因此,Redis也 ...
- 分分钟弄明白UML中泛化 , 实现 , 关联, 聚合, 组合, 依赖
在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization), 关联(Association), 聚合(Aggregation), 组合(Compo ...
- .Net Core使用Socket与树莓派进行通信
前言 去年买的树莓派一直放在抽屉里吃灰,前些阵子Debian 9发布,也不出意外的支持了树莓派. 于是重新拿出读卡器又重新了装上了Debian桌面版系统. 介绍 现在这个东西目前的程度只是了解一下Py ...
- (微信小程序)一 : 初识微信小程序
首先看过angularjs的同学们在看微信小程序的创始文件应该不算很陌生吧. 需要看的 先是文件目录 看完这个目录..得知 ( 一 ) pages 他存放于多个页面 如 index ,log ...
- Jave Web阿里云短信服务发送验证码
首先得在阿里云根据流程开通短信服务,申请签名和模版,具体看文档 因为这是个web项目,用到了thymeleaf模板,所以在pom.xml中加入如下依赖 <dependency> <g ...