我正在尝试使用客户端Javascript中的OPENROWSET通过SQL Server访问大型Oracle数据库,并且没有太多运气。以下是详细信息:
我的想法是定义一个函数,它将采用我自己的参数化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有关,我希望那里的设置是正确的,因为上面提到的视图有效。
我尝试过的另一种方法是在Open语句中删除封闭的EXEC:
rs.Open(e,db);
但这会产生相同的错误。
我也尝试将OPENROWSET放在存储过程中。这在从SQL Server Management Studio中执行时非常有效,但在从Javascript调用存储过程时失败并显示相同的错误消息。
我正在尝试做什么?如果是这样,你能推荐如何修复我的代码吗?或者是一种完全不同的方法吗?
欢迎提供任何提示或相关信息。提前谢谢。
答案 0 :(得分:1)
我自己也在回答这个问题。我找到了答案,我对结果不满意。已经工作的函数是在我的个人用户ID下运行的,我有db-owner权限。要使 ad hoc 访问工作,我需要将DisallowAdhocAccess
注册表设置为0,或者为Web访问中使用的用户ID提供db-owner权限。因为这是一个安全性很高的共享服务器,所以我不会更改注册表设置,这会比我的数据库影响更多。我认为第二种选择同样危险。
因此,我显然不得不强迫用户安装Oracle Instant Client,因此我可以直接在客户端Javascript中打开与Oracle数据库的ADO连接。
我仍然会欢迎任何其他想法。
答案 1 :(得分:0)
打开与数据库的客户端ADO连接是一个巨大的安全禁忌。您实际上是在向用户提供数据库的连接凭据,并且敢于在数据库安全性中找到漏洞。即使您的受众是公司内部的,您也可能遇到没有安装oracle驱动程序(或旧版本)的问题。为什么不隐藏JSON调用背后的Oracle查询?这样,您可以在服务器端清理数据库输入,并且您的用户从未以纯文本形式接收数据库连接凭据。
答案 2 :(得分:0)
尝试在sql server框中推荐链接服务器 http://msdn.microsoft.com/en-us/library/ms188279.aspx用于获取oracle数据