当前位置: 首页 > 知识库问答 >
问题:

sqlserver - 连接 SqlServer 的问题?为什么一定需要通过 DSN?

李敏学
2023-05-02

有个老项目使用的是 ASP+SQL Server,今天把它迁移到新服务器上去。
于是就在新服务器上安装好 IIS 和 SQL Server,就把老服务器上的数据给迁移过来。结果发现 ASP 死活连接不上数据库,检查后发现数据库正常、ASP 也正常,但是就是连接不上。提示找不到数据库 ODBC 什么的……
后来百度一下说需要在 ODBC 数据源管理中新建一个用户 DSN,照做后正常了。
为什么不是像 PHP 连接 MySQL 那样直接连接,非得弄个这个环节干嘛?

共有1个答案

郑胡媚
2023-05-02

当然可以呀,看你项目代码怎么写的呗。代码里通过 ODBC 连接的数据库,那就需要配置 DSN 呗(你用的图形化界面工具本质上是配置了一个 ini 文件);通过数据库驱动直连的数据库,就不需要呗。这跟 ASP 其实没什么关系。


之所以你有这个疑问估计是不太清楚 ODBC 是干嘛的。概念性的内容我就不写了,你自己搜都能搜到。我就讲一下为什么会出现 ODBC。

首先我们要知道编程语言跟数据库之间的通信的“桥梁” —— 数据库驱动(不同编程语言或数据库给起名叫 Driver、Connector 或者 Provider,其实都是一回事儿)。数据库驱动内部封装了跟数据库通信的逻辑,对外提供了一组 API 供开发者使用。这样开发者就无需关心到底是如何跟数据库通信的,只需要会使用这些 API 就可以了。

比如你提到的 PHP,它的 MySql 驱动就是 mysqlnd,你在安装 php-mysqli 或 php-pdo 时会依赖于它。

假如你现在正在使用一门叫做 SF 的编程语言,那么跟数据库打交道的方式就会是这样:

SF → DB API → DB Driver for SF → DB

但这样还会有两个问题:

  1. 不同数据库驱动提供的 API 是不同的,更换数据库就得重写代码,怎么办?
  2. 某些编程语言或数据库很小众,无法为你所使用的编程语言单独提供驱动,怎么办?

对于第一个问题,很多编程语言选择了再封装一层。比如 PHP 的 PDO 就是干这个事儿的。但封装总有穷尽时,可数据库是无穷无尽的。PDO 只能支持常见的十来种数据库,但自有数据库以来出现过的数据库产品可有几百种。有一天你真的需要使用某种在 PDO 支持范围之外的数据库怎么办?

对于第二个问题,绝大多数数据库起码都会提供一个针对 C 语言的驱动,而绝大多数编程语言也都会支持调用 C 库。所以你可以选择基于此来封装一层。但第一不那么优雅,第二不是所有开发者都精于 C 的。

所以看似两个问题都有解,但总归是解的不那么完美。

于是乎 ODBC 应运而生了。它独立于编程语言和数据库而存在,站在更高的层次上做了抽象。对于编程语言来说,不需要再关心到底使用那个数据库驱动提供的 API 了;对于数据库来说,也不用再为每个编程语言都提供一个驱动了。有了 ODBC 之后,再跟数据库打交道的方式就变成了这样:

SF → ODBC API → ODBC → DB Driver for ODBC → DB

P.S. 上个世纪末没有规范之前比我上面描述的还要混乱多了,远不止一个驱动的问题,那个时候甚至连 SQL 都没统一,不像今天虽说各家也会有一些独特的特性或语法,但起码都遵循 ISO-9075。这里就不展开写了,感兴趣的话可以自行去了解。


自打 ODBC 出现后,因为确实思想很先进、也没有同类竞品,加之微软爸爸的大力推广,所以很快就成了一项事实标准。现如今,几乎所有数据库都会去兼容 ODBC,而几乎所有编程语言也都支持以 ODBC 形式访问数据库。

当然了,对于今天的开发者来说,只要你用的是主流编程语言和主流数据库,一般也不会使用 ODBC 这种方式去连接数据库。但人生总归有意外不是?保不齐哪天项目需要,你就得去用一个小众语言或者小众数据库了。

 类似资料:
  • 我尝试连接到本地sqlserver express 2008 R2。 当我将服务器名指定为127.0.0.1时,如 String url=“jdbc:sqlserver://127.0.0.1;databaseName=mydatabase;”; 配置:我设置TCP/IP连接启用。我在ipall部分将tcp动态端口设置为1433。已启用命名实例->,它不会影响连接。

  • 问题内容: 我一直在尝试查找有关我的查询的问题。该查询实际上是由HQL的hibernate生成的,但是生成的SQL并没有达到我的期望。稍微修改SQL会产生正确的结果,但是我不确定为什么修改会有所不同。 原始查询(不返回任何行) 修改的查询-用逗号替换交叉联接(隐式交叉联接) 返回一行 我的理解可能是错误的,因为写作与Writing相同。所以我不明白为什么查询返回不同的结果。 与导致此问题的第一个查

  • 问题内容: 我有一张桌子,我需要在99%的时间内自动分配ID(其他1%似乎使用身份列来排除)。因此,我有一个存储过程来获取以下行中的下一个ID: `` 检查必须检查用户是否手动使用了ID并找到下一个未使用的ID。 当我依次调用它并返回1、2、3时,它可以正常工作。我需要做的是在多个进程同时调用此方法的情况下提供一些锁定。理想情况下,我只需要它专用于围绕此代码锁定last_auto_id表,以便第二

  • 本文向大家介绍何谓SQLSERVER参数嗅探问题,包括了何谓SQLSERVER参数嗅探问题的使用技巧和注意事项,需要的朋友参考一下 大家听到“嗅探”这个词应该会觉得跟黑客肯定有关系吧,使用工具嗅探一下参数,然后截获,脱裤o(∩_∩)o 。 事实上,我觉得大家太敏感了,其实这篇文章跟数据库安全没有什么关系,实际上跟数据库性能调优有关 相信大家有泡SQLSERVER论坛的话不多不少应该都会见过“参数嗅

  • 问题内容: 使用JDBC连接池工具(如DBCP或c3p0)有什么好处? 如果只有 一个* 用户的 小型CRUD 应用程序,我们是否可以将 一个 连接会话创建为一个 单例 ? * PS :我正在构建一个带有小型数据库(5个表)的小型后端应用程序。 问题答案: 从Jon Skeet的答案到连接和语句池的好处是什么?: 创建到数据库服务器的网络连接是(相对)昂贵的。同样,要求服务器准备SQL语句(相对)

  • 问题内容: 我正在将Visual Studio 2017 for Mac与dotnet Core和EF Core一起使用。在Docker容器中设置mssql映像后,我试图添加连接字符串,但抛出连接错误。我尝试使用不同的选项(例如ip地址,容器名称,主机名等)作为服务器名称,但是它们都不起作用。 带有容器名称 主机名: 通过在终端中使用本地主机进行连接时,其成功连接 但是在运行应用程序时,连接失败。