【问题标题】:Accessing Oracle DB through SQL Server using OPENROWSET使用 OPENROWSET 通过 SQL Server 访问 Oracle DB
【发布时间】:2009-01-15 19:18:38
【问题描述】:

我正在尝试使用客户端 Javascript 中的 OPENROWSET 通过 SQL Server 访问大型 Oracle 数据库,但运气不佳。具体如下:

  • 使用 OPENROWSET 访问 Oracle 数据库的 SQL Server 视图运行良好,因此我知道我有有效的连接字符串参数。但是,新要求是针对依赖于客户端选择的极其动态的 Oracle 查询,而我无法让动态(甚至参数化的)Oracle 查询在 SQL Server 视图或存储过程中工作。
  • 对 SQL Server 数据库的客户端访问与动态和参数化查询完美配合。
  • 我不能指望拥有任何 Oracle 客户端软件的客户端。因此,必须通过 SQL Server 数据库、使用视图、存储过程或使用 OPENROWSET 的动态查询来访问 Oracle 数据库。
  • 由于 SQL Server 数据库位于共享服务器上,因此不允许我使用全局链接数据库。

我的想法是定义一个函数,该函数将采用我自己版本的参数化 Oracle 查询,进行参数替换,将查询​​包装在 OPENROWSET 中,然后在 SQL Server 中执行,返回结果记录集。这是示例代码:

// db is a global variable containing an ADODB.Connection opened to the SQL Server DB
// rs is a global variable containing an ADODB.Recordset
. . .
ss = "SELECT myfield FROM mytable WHERE {param0} ORDER BY myfield;";
OracleQuery(ss,["somefield='" + somevalue + "'"]);
. . .
function OracleQuery(sql,params) {
  var s = sql;
  var i;
  for (i = 0; i < params.length; i++) s = s.replace("{param" + i + "}",params[i]);
  var e = "SELECT * FROM OPENROWSET('MSDAORA','(connect-string-values)';"
    + "'user';'pass','" + s.split("'").join("''") + "') q";
  try {
    rs.Open("EXEC ('" + e.split("'").join("''") + "')",db);
  } catch (eobj) {
    alert("SQL ERROR: " + eobj.description + "\nSQL: " + e);
  }
}

我得到的 SQL 错误是 Ad hoc access to OLE DB provider 'MSDAORA' has been denied. You must access this provider through a linked server.,这对我来说毫无意义。 Microsoft 对此错误的解释与注册表设置 (DisallowAdhocAccess) 有关。这在我的 PC 上设置正确,但肯定与 DB 服务器有关,而不是客户端 PC,我希望那里的设置是正确的,因为上面提到的视图有效。

我尝试过的一种替代方法是消除 Open 语句中的封闭 EXEC:

rs.Open(e,db);

但这会产生同样的错误。

我还尝试将 OPENROWSET 放入存储过程中。这在 SQL Server Management Studio 中执行时完美运行,但在从 Javascript 调用存储过程时失败并显示相同的错误消息。

我正在尝试做的事情可能吗?如果是这样,你能推荐如何修复我的代码吗?还是需要完全不同的方法?

欢迎提供任何提示或相关信息。提前致谢。

【问题讨论】:

    标签: javascript sql-server oracle openrowset


    【解决方案1】:

    我自己来回答这个问题。我找到了答案,但我对结果不满意。有效的功能正在我的个人用户 ID 下运行,并且我拥有 db-owner 权限。要使 ad hoc 访问正常工作,我需要将 DisallowAdhocAccess 注册表设置设置为 0,或者将 db-owner 权限授予 Web 访问中使用的用户 ID。因为这是一个具有严格安全性的共享服务器,所以我不会被允许更改注册表设置,这会比我的数据库影响更多。而且我认为第二种选择同样危险。

    因此,我显然坚持强迫用户安装 Oracle Instant Client,以便我可以直接在客户端 Javascript 中打开到 Oracle 数据库的 ADO 连接。

    我仍然欢迎对此提出任何其他想法。

    【讨论】:

      【解决方案2】:

      打开到数据库的客户端 ADO 连接是一个巨大的安全禁忌。您实际上是在向用户提供与您的数据库的连接凭据,并让他们敢于发现您的数据库安全性中的漏洞。即使您的受众是您公司的内部人员,您也可能会遇到他们没有安装 oracle 驱动程序(或旧版本)的问题。为什么不把 Oracle 查询隐藏在 JSON 调用后面呢?这样,您可以在服务器端清理数据库输入,并且您的用户永远不会收到纯文本的数据库连接凭据。

      【讨论】:

      • 我同意。如果我能让查询在服务器端工作,我会这样做。问题是由于 OPENROWSET 语法的限制,我根本无法让查询在服务器上运行。
      【解决方案3】:

      尝试在您的 sqlserver 框中推荐一个链接服务器 Linked Servers (Database Engine) 用于获取 oracle 数据

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多