OLE DB的SAS提供程序(SAS.IOMProvider)不适用于ObjectPool

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OLE DB的SAS提供程序(SAS.IOMProvider)不适用于ObjectPool相关的知识,希望对你有一定的参考价值。

我正在使用SAS Integration Technologies COM组件从C#.NET项目连接到SAS服务器。我想将语句提交给SAS工作区,然后使用OLE DB提供程序(SAS.IOMProvider)从SAS加载输出数据集。我可以使用这样的代码成功完成此操作:

static int Main(string[] args)
{
    var keeper = new ObjectKeeper();
    var factory = new ObjectFactoryMulti2();
    var server = new ServerDef()
    {
        MachineDNSName = "sas.server.com",
        Protocol = Protocols.ProtocolBridge,
        Port = 8591,
        BridgeSecurityPackage = "Negotiate",
    };
    var workspace = (IWorkspace)factory.CreateObjectByServer("Workspace1", true, server, null, null);

    keeper.AddObject(1, workspace.UniqueIdentifier, workspace);

    try
    {
        using (var conn = new OleDbConnection("Provider=SAS.IOMProvider.1; Data Source=iom-id://" + workspace.UniqueIdentifier))
        {
            // success
            conn.Open();
        }
    }
    catch (Exception ex)
    {
        System.Console.Error.WriteLine(ex.ToString());
        return 1;
    }
    finally
    {
        keeper.RemoveObject(workspace);
        workspace.Close();
    }

    return 0;
}

但是,当我尝试使用ObjectPoolObjectFactoryMulti2功能时,OLE DB连接不起作用。它总是抛出“无法找到对象;确保它先前已添加到对象管理器中。”这是不起作用的代码:

static int Main(string[] args)
{
    var keeper = new ObjectKeeper();
    var factory = new ObjectFactoryMulti2();
    var server = new ServerDef()
    {
        MachineDNSName = "sas.server.com`",
        Protocol = Protocols.ProtocolBridge,
        Port = 8591,
        BridgeSecurityPackage = "Negotiate",
        MaxPerObjectPool = Environment.ProcessorCount,
        RunForever = true,
        RecycleActivationLimit = 100,
    };
    var login = new LoginDef();

    var pool = factory.ObjectPools.CreatePoolByServer("Pool1", server, login);
    var lease = pool.GetPooledObject(null, null, 5000);
    var workspace = (IWorkspace)lease.SASObject;

    keeper.AddObject(1, workspace.UniqueIdentifier, workspace);

    try
    {
        using (var conn = new OleDbConnection("Provider=SAS.IOMProvider.1; Data Source=iom-id://" + workspace.UniqueIdentifier))
        {
            // throws System.Data.OleDb.OleDbException: 'The object 1EFCE532-99BA-4A27-AF37-574EAE1CD04C could not be found; make sure it was previously added to the object keeper.'
            conn.Open();
        }
    }
    catch (Exception ex)
    {
        System.Console.Error.WriteLine(ex.ToString());
        return 1;
    }
    finally
    {
        keeper.RemoveObject(workspace);
        lease.ReturnToPool();
        pool.Shutdown();
    }

    return 0;
}

有没有办法在SAS OLE DB提供程序中使用SAS连接池?

答案

SAS支持部门对此问题给出了很好的答案。使用连接池时,必须将工作空间强制转换为IServerStatus并使用其ServerStatusUniqueID属性而不是IWorkspace.UniqueIdentifier进行连接。

var pool = factory.ObjectPools.CreatePoolByServer("Pool1", server, login);
var lease = pool.GetPooledObject(null, null, 5000);
var workspace = (IWorkspace)lease.SASObject;
var status = (IServerStatus)lease.SASObject;

keeper.AddObject(1, workspace.UniqueIdentifier, workspace);

using (var conn = new OleDbConnection("Provider=SAS.IOMProvider.1; Data Source=iom-id://" + status.ServerStatusUniqueID))
{
    // success
    conn.Open();
}

keeper.RemoveObject(workspace);
lease.ReturnToPool();

以上是关于OLE DB的SAS提供程序(SAS.IOMProvider)不适用于ObjectPool的主要内容,如果未能解决你的问题,请参考以下文章

如何获取已安装的 OLE DB 提供程序的列表?

用于 ODBC 驱动程序的 Microsoft OLE DB 提供程序错误“80004005”

用于ODBC驱动程序的OLE DB提供程序错误“80004005”

通过 Microsoft OLE DB 提供程序使用 EXCEL 作为数据源

Microsoft Office 12.0 Access 数据库引擎 OLE DB 提供程序问题

OLE DB 提供程序'对于链接服务器返回的数据与预期的数据长度不匹配