原文:MSSQL连接字符串,你真的清楚吗?

几年前当我第一次面试时,考官发现我是个新手于是他让我写个连接字符串,虽然当时就知道X种连接字符串的写法,但是当时却没能写对一个,工作多年后我仍然不能写一个正确的连接字符串,但我知道打发新人时,让他写连接字符串是个不错的方法.

   以下是一个常用的ADO.NET 连接MSSQL的字符串
  "Data Source=.;Initial Catalog=MyDBA;Integrated Security=SSPI"
  在IIS 环境下 我们也许会这么写
  "Data Source=.;Initial Catalog=MyDBA;User Id=用户名;pwd=一般人我不告诉他;"
  
使用高效的协议(虽然我们一直这么做,但一直没注意)
  首先要搞清楚我们是使用什么方式与MSSQL数据库服务沟通的,当然微软产品的好处是即使你不知道,他也会帮你选择一个最合适的方式,在IIS跟MSSQL同台服务器的情况下,默认使用共享内存.
图1)

要确认ADO.Net建立的是什么方式的连接可以通过,企业管理器中->管理->进程信息

可以看到ADO.NET提供程序,.Net SqlClient data Provider

使用LPC(本地调用,即共享内存)

 如果你把上面的连接字符串改成"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI"
注意我的电脑上安装了多个SQL2000实例,其中一个为SQL2K ,使用上面的连接字符串打开一个连接后,再查看进程信息,发现LPC 现在变成了Tcp/IP(注意是.Net SqlClient Data provider对应的行)这个表明现在你启用了TCP/IP来连接数据库,
当然在IIS跟SQL同服务器的情况下建议你使用LPC,这样速度跟性能都比较优越.

在连接字符串中使用端口
一般异地连接时我们多使用tcp/ip协议,默认端口是1433,有时候你可能想改变这个端口,为此你需要使用"服务器网络实用工具"(在开始->Microsoft SQL Server下面),在里面配置Tcp/ip 协议并指定一个新的端口.

    这里指定了8888 为实例SQL2K的新端口,注意请不要将"隐藏服务器(H)"选择中,保存更改后就可以下面的连接字符串进行连接了"Data Source=127.0.0.1,8888;Initial Catalog=MyDBA;User ID=sa ",同样在进程信息里你能看到ADO.NET的一条用户名为sa的TCP/IP连接.但是当我们试图从远程连接这台SQL服务器时通常会出现问题,一般服务器上都有防火墙,而且只开放web,ftp,远程桌面等几个有限的端口,而你上面指定8888未在其列,因此当你在异地来连接数据库时会报错,(另外连接字符串如"Data Source=60.188.86.49,8888;Initial Catalog=MyDBA;User ID=sa;pwd=" ,中需要注意的是端口号跟IP或域名之间用逗号","隔开)为解决此问题你需要在防火墙中开放8888端口.
   完成后,你可以使用上面IP+端口的形式访问数据库了,不过你在使用以上连接字符串前,是否尝试过类似
"Data Source=www.wow52.cn\SQL2K;Initial Catalog=MyDBA;User ID=sa;pwd=;" 形式的连接字符串呢,这里采用域名加实例名的样子,可能你尝试了下发现行不通,反正我当时是这样做过但发现不行,虽然感觉这个形式很直观,但是怎么就不行呢?
   当然如果你细心的话,回过头去看上文有个"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI"形式的连接字符串,这个是IP+实例的形式,本质上已经是域名+实例的形式了,那么为什么不行呢?问题同样是出在防火墙上面,不过这次你需要开放的是一个UDP端口1434以给运行SQL Server 解析协议 (SSRP)的服务使用,当你使用域名+实例名访问时,解析服务会解析成 IP+端口的形式进行数据库连接. 现在你通过企业管理器中的进程信息查看时,可以看到一个TCP/IP连接了,
SQL Server 解析协议 在SQL2005中被SQL Server Browser 取代,在需要进行远程连接,并且采用域名或IP+实例名的形式时,你需要启动这个服务,并且在防火墙中开放相应端口. 最后关于端口部分,还有一点是SQL2000,跟SQL2005多支持动态端口,也就是把端口设置为0(SQL2005 具体参考配置工具),这个时候为使数据库能在异地正确访问,你需要在防火墙中以添加程序的形式把sqlserver.exe添加进去,如实例SQL2k的程序位置是
D:\Program Files\Microsoft SQL Server\MSSQL$SQL2K\Binn\sqlservr.exe,具体取决于你的安装位置,SQL2005可以在服务器网络配置工具里查看. 除了需要添加sqlserver.exe程序外,你还需要开放1434 UDP端口,或者在使用SQL2005时把C:\Program Files\Microsoft SQL Server\90\Shared\sqlbrowser.exe 添加到防火墙里, sqlbrowser.exe 使用的也是1434 UDP端口.

以上所讲述在我的MSSQL2000里都不行!
  

如果你不幸遇到这样的情况,最重要的一点是查看你sql的版本,请在查询分析器里运行 Select @@Version,或者看帮助菜单中的"关于..." 如果版本不是8.00.2039(现在说的是SQL2000),那么赶紧升级把,下个SQLSP4来打上.
如果打上补丁还无济于事,那么请确定你在SQL Server网络实用工具中启用了TPC/IP协议,并在防火墙中开放了相关端口.

连接字符串中的一些属性
 
  Connection lifetime 连接生存时间,默认为0,表示无限长,单位为秒.在SQL集群环境中我们才设置为具体的数值.

  Connection timeout 连接生成时间,默认为15秒,通俗的讲当你conn.Open等15秒后还没连接成功,那么就会抛出一个连接超时的错误,这也是为什么其他错误来的那么突然,而数据库连接超时错误,非要你等15秒的原因了.

  Pooling 是否使用连接池, 默认是起用的,使用Pooling=false来禁止.

  Min Pool Size,Max Pool Size 默认情况下最小是0,最大是100.

  关于pooling属性在上面所有的连接字符串中多是默认开启的,连接池能有效的提高数据库访问性能,因为创建一个连接需要消耗很多资源,尤其是进行异地访问时(一般指局域网,最好不要进行跨internet的数据库访问)更加如此,因此你在多数情况下不需要显式的禁止(也许你没在意微软一直帮你开通着), 事实上在你使用 conn.open() ,conn.close() 多少数情况下不是真的打开一个连接,而是向连接池中取一条可用连接,跟归还一条连接,conn.open操作只有在池中没有可用连接时才会创建一条连接,当然如果池中可用接数目达到Max Pool Size时,他将不再创建新的连接,而是等待一条可用连接的到来,这个时间是Connection timeout. 当然你的conn.Open操作涉及的连接池,取决于你的连接字符串,比如:
"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI"

"Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI;" ,注意后面多了";"
会开启两个独立的连接池,ADO.NET 判断字符串是否相同的依据是对字符串进行2进制的比较,所以任何变动(空格,大小写)都会被判断为不同的连接字符串.
有如下代码
-----------------------------------
string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI;";
for(int i=0;i<10;i++){
  SqlConnection conn=new SqlConnection(strConn);
  conn.Open();
  conn.Close()
}

string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI;";
for(int i=0;i<10;i++){
  strConn +=" "; //空格
  SqlConnection conn=new SqlConnection(strConn);
  conn.Open();
  conn.Close()
}
两段代码分别运行,看企业管理器->管理->进程信息(请刷新先) ,可以看到前面的只启用了一个进程,而后面的则启用了10个进程,每个进程对应一条连接.前一段代码10个open +close()操作使用的是同一个连接池中的同一个连接,而后一个则开启了10个连接池,每个连接池中有一个连接.

再看下面的代码
            for (int i = 0; i <= 10; i++)
            {
                Thread t = new Thread(new ThreadStart(Command));
                t.Start();
            }
---------------------
//Command定义
private void Command(){
string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI;";
  Sqlconnection conn=new SqlConnection(strConn);
 SqlCommand cmd=new SqlCommand("一个运行比较长的查询",conn);
  conn.Open();
  cmd.ExecuteNonQuery();
  
  conn.Close()
}
  运行后可以看,企业管理器->管理->进程信息里会开启10个到MyDBA数据库的连接进程,但是需要注意的是,这10个进程是属于同个连接池的,为了证明这一点你可以将上面的连接字符串改为
 private void command(){
string strConn="Data Source=127.0.0.1\SQL2K;Initial Catalog=MyDBA;Integrated
Security=SSPI;Max pool Size=5;"; //加了Max Pool Size=5;
  SqlConnection conn=new SqlConnection(strConn);
 SqlCommand cmd=new SqlCommand("一个运行比较长的查询",conn);
  conn.Open();
  cmd.ExecuteNonQuery();
  
  conn.Close()
}
结果可以看到他只开启了5个到MyDBA数据库的连接,这证明他们是同个连接池的.当然这里能成功演示的前提是,cmd执行的任务时间要在15秒内,不然会出现后5个线程连接超时,另外使用SQL2000 的跟踪工具(SQL2005中是,SQL Server Profiler)是你观察以上实验的一个绝好的工具!

MSSQL连接字符串,你真的清楚吗?的更多相关文章

  1. MSSQL Server数据库的四种连接方法和sql连接字符串

    MSSQL Server数据库的四种连接方法和sql连接字符串 分类: [ 03 ] C#(131) [ 07 ] SQL Server(68) [ 01 ] .NET(189) 今天用SQL Ser ...

  2. Java基础 -- 连接字符串时,使用+还是StringBuilder

    结论 1-源代码中使用的+连接,实际上都使用的是StringBuilder. 2-用jad工具反编译,好处之一就是可以同时生成字节码和源代码.这样可以进行对照研究. ----------------- ...

  3. 第19课-数据库开发及ado.net ADO.NET--SQLDataReader使用.SqlProFiler演示.ADoNET连接池,参数化查询.SQLHelper .通过App.Config文件获得连接字符串

    第19课-数据库开发及ado.net ADO.NET--SQLDataReader使用.SqlProFiler演示.ADoNET连接池,参数化查询.SQLHelper .通过App.Config文件获 ...

  4. ASP.NET web.config中的连接字符串

    在ASP.NET的web.config中,可以用两种方式来写连接字符串的配置. <configuration> <appSettings> <add key=" ...

  5. 使用配置文件定义ADO.NET 的连接字符串

    最近一直在学习ADO.NET的相关知识,发现要对数据库操作的地方都要先创建一个连接字符串: string constr ="Data Source=(local);Initial Catal ...

  6. 用SQL Server(T-SQL)获取连接字符串

    一般情况下,C# 连接SQL Server的字符串可以直接按照说明文档直接手动写出来,或者也可以参考大名鼎鼎的connectionstrings手动拼写 但是如果你已经连接到SQL Server也可以 ...

  7. ASP.NET MVC 5 - 创建连接字符串(Connection String)并使用SQL Server LocalDB

    您创建的MovieDBContext类负责处理连接到数据库,并将Movie对象映射到数据库记录的任务中.你可能会问一个问题,如何指定它将连接到数据库? 实际上,确实没有指定要使用的数据库,Entity ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (38) ------ 第七章 使用对象服务之动态创建连接字符串和从数据库读取模型

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 第七章 使用对象服务 本章篇幅适中,对真实应用中的常见问题提供了切实可行的解决方案. ...

  9. EF6 Create Different DataContext on runtime(运行时改变连接字符串)

    引言   在使用EF时,有时我们需要在程序运行过程中动态更改EF的连接字符串,但不幸的时EF是否对 ConfigurationManager.RefreshSection("xxx" ...

随机推荐

  1. Gulp如何编译sass

    Gulp 是一个自动化工具,前端开发者可以使用它来处理常见任务: 1.搭建web服务器 2.文件保存时自动重载浏览器 3.使用预处理器如Sass.LESS 4.优化资源,比如压缩CSS.JavaScr ...

  2. 用JQuery实现表格隔行变色和突出显示当前行

    用JQuery实现表格隔行变色和突出显示当前行 上源码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "htt ...

  3. java_访问权限修饰符

    java的访问权限修饰符有四种,根据权限由大到小的顺序为:public,protected,包访问权限(默认,没有修饰符),private. 根据修饰的东西不同,详细介绍如下: 1.修饰类的话分为两种 ...

  4. Android Studio 2.3 解决小米手机调试安装apk失败问题

    在开发者选项里面,拉到底,把miui优化选项去掉就好了. 参考资料 [问题反馈] Android Studio 2.3 在红米note3手机中 调试安装Apk失败

  5. install svn server in Ubuntu

    1. #安装服务 apt-get install subversionapt-get install libapache2-svnapt-get install apache2apt-get inst ...

  6. JAVA和C#检测IP地址段是否交叉和获取地址段IP列表的方法

    一.说明 我们经常编程时,需要对一个DIDR地段计算其可用IP地址,或者验证某个IP是否被包含在一个地址段中. 二.工具 1.Java 可以使用 cidr-ip-trie库解决. https://gi ...

  7. node模块加载机制。

  8. [教学] Delphi IDE 文件搜寻功能

    Delphi IDE 提供了一个方便的文件搜寻功能,操作如下: 点 Search 选单内的 Find in Files... 例如我们想搜寻 JFile 需要引用那一个源码,可输入如下: 输入关键字: ...

  9. 内存测试——Android Studio自带内存检测功能

    AndroidStudio 自带 CPU 和内存检测工具,绘制出变化图,可以直观明了的看出内存和cpu的变化曲线. 手机连接电脑,选择要调试的手机,选择要检测的应用进程,Memory是内存监控,CPU ...

  10. 【Mac + ATX基于uiautomator2】使用weditor时,报错:requests.exceptions.ConnectionError: (&#39;Connection aborted.&#39;, ConnectionResetError(54, &#39;Connection reset by peer&#39;))

    产生以下原因找到了:是因为启动了appium,两者冲突,不能同时使用. 之前讲过怎么安装u2([Mac安装,ATX基于uiautomator2]之安装步骤)以及使用weditor, 但是经过一段时间, ...