在C#中通过OCI来访问Oracle数据库,但是在调用OCIServerAttach接口时出现问题。
Oracle官方的OCI文档中,OCIServerAttach接口的声明方式如下:
sword OCIServerAttach (OCIServer *srvhp, OCIError *errhp,
CONST OraText *dblink, sb4 dblink_len, ub4 mode); 在.NET中,为了调用OCI接口,创建以下类:
internal class OciNativeMethods
{
[DllImport(@"oci.dll", EntryPoint = "OCIEnvCreate", CharSet = CharSet.Unicode)]
internal static extern int OCIEnvCreate(out IntPtr envp, int mode, IntPtr ctxp, IntPtr malocfp, IntPtr ralocfp, IntPtr mfreefp, int xtramem_sz, IntPtr usrmempp); [DllImport(@"oci.dll", EntryPoint = "OCIHandleAlloc", CharSet = CharSet.Unicode)]
internal static extern int OCIHandleAlloc(IntPtr parenth, out IntPtr hndlpp, int type, int xtramem_sz, IntPtr usrmempp); [DllImport(@"oci.dll", EntryPoint = "OCIHandleFree", CharSet = CharSet.Unicode)]
internal static extern int OCIHandleFree(IntPtr hndlp, int type); [DllImport(@"oci.dll", EntryPoint = "OCIServerAttach", CharSet = CharSet.Unicode)]
internal static extern int OCIServerAttach(IntPtr srvhp, IntPtr errhp, string dblink, int dblink_len, int mode); [DllImport(@"oci.dll", EntryPoint = "OCIErrorGet", CharSet = CharSet.Unicode)]
internal static extern int OCIErrorGet(IntPtr hndlp, int recordno, IntPtr sqlstate, out int errcodep, IntPtr bufp, int bufsiz, int type); ...... internal const int OCI_DEFAULT = 0x00000000;
internal const int OCI_THREADED = 0x00000001;
internal const int OCI_OBJECT = 0x00000002;
internal const int OCI_EVENTS = 0x00000004;
internal const int OCI_SHARED = 0x00000010; ......
} internal class OciContext
{
internal IntPtr EnviromentHandle = IntPtr.Zero;
internal IntPtr ServerHandle = IntPtr.Zero;
internal IntPtr ServerConextHandle = IntPtr.Zero;
internal IntPtr ErrorHandle = IntPtr.Zero;
internal IntPtr SessionHandle = IntPtr.Zero;
internal IntPtr StatementHandle = IntPtr.Zero;
} 以下为测试代码:
public partial class Form1 : Form
{
...... private void button1_Click(object sender, EventArgs e)
{
OciContext context = new OciContext();
int status = Oci_InitContext(context);
DebugLog.Write("初始化OCI上下文失败,返回状态: " + status);
Console.WriteLine("初始化OCI上下文失败,返回状态: " + status);
} /// <summary>
/// 初始化OCI上下文。
/// </summary>
/// <param name="context">OCI上下文。 </param>
/// <returns>执行状态。 </returns>
private int Oci_InitContext(OciContext context)
{
//创建OCI环境
int status = OciNativeMethods.OCIEnvCreate(out context.EnviromentHandle, OciNativeMethods.OCI_DEFAULT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //申请错误句柄
status = OciNativeMethods.OCIHandleAlloc(context.EnviromentHandle, out context.ErrorHandle, OciNativeMethods.OCI_HTYPE_ERROR, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //申请服务器句柄
status = OciNativeMethods.OCIHandleAlloc(context.EnviromentHandle, out context.ServerHandle, OciNativeMethods.OCI_HTYPE_SERVER, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //申请服务器上下文句柄S
status = OciNativeMethods.OCIHandleAlloc(context.EnviromentHandle, out context.ServerConextHandle, OciNativeMethods.OCI_HTYPE_SVCCTX, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //连接数据库服务器
string dblink = "ORCL";
status = OciNativeMethods.OCIServerAttach(context.ServerHandle, context.ErrorHandle, dblink, dblink.Length < < 1, OciNativeMethods.OCI_DEFAULT);
if (status != OciNativeMethods.OCI_SUCCESS)
{
Console.WriteLine("连接失败:" + Oci_GetError(context.ErrorHandle));
return status;
}
Console.WriteLine("连接成功。"); ...... return status;
} ......
} 执行到红色部分时出错,返回的状态代码为-1。
需要说明的是,我在本机上装了一个Oracle10g,SID是ORCL,tnsnames.ora文件的完整内容是:
# tnsnames.ora Network Configuration File: c:\oracle\product\10.2.0\db_1\network\admin\tnsnames.ora
# Generated by Oracle configuration tools. ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = ms-c3a782ca83be)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
) EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
) 调用OCIServerAttach失败后,通过Oci_GetError接口获取到错误信息:
ORA-12154: TNS: 无法解析指定的连接标识符。
我用PL/SQL Developer是可以登录的。请大家帮忙看看是怎么回事,急等,谢谢。
Oracle官方的OCI文档中,OCIServerAttach接口的声明方式如下:
sword OCIServerAttach (OCIServer *srvhp, OCIError *errhp,
CONST OraText *dblink, sb4 dblink_len, ub4 mode); 在.NET中,为了调用OCI接口,创建以下类:
internal class OciNativeMethods
{
[DllImport(@"oci.dll", EntryPoint = "OCIEnvCreate", CharSet = CharSet.Unicode)]
internal static extern int OCIEnvCreate(out IntPtr envp, int mode, IntPtr ctxp, IntPtr malocfp, IntPtr ralocfp, IntPtr mfreefp, int xtramem_sz, IntPtr usrmempp); [DllImport(@"oci.dll", EntryPoint = "OCIHandleAlloc", CharSet = CharSet.Unicode)]
internal static extern int OCIHandleAlloc(IntPtr parenth, out IntPtr hndlpp, int type, int xtramem_sz, IntPtr usrmempp); [DllImport(@"oci.dll", EntryPoint = "OCIHandleFree", CharSet = CharSet.Unicode)]
internal static extern int OCIHandleFree(IntPtr hndlp, int type); [DllImport(@"oci.dll", EntryPoint = "OCIServerAttach", CharSet = CharSet.Unicode)]
internal static extern int OCIServerAttach(IntPtr srvhp, IntPtr errhp, string dblink, int dblink_len, int mode); [DllImport(@"oci.dll", EntryPoint = "OCIErrorGet", CharSet = CharSet.Unicode)]
internal static extern int OCIErrorGet(IntPtr hndlp, int recordno, IntPtr sqlstate, out int errcodep, IntPtr bufp, int bufsiz, int type); ...... internal const int OCI_DEFAULT = 0x00000000;
internal const int OCI_THREADED = 0x00000001;
internal const int OCI_OBJECT = 0x00000002;
internal const int OCI_EVENTS = 0x00000004;
internal const int OCI_SHARED = 0x00000010; ......
} internal class OciContext
{
internal IntPtr EnviromentHandle = IntPtr.Zero;
internal IntPtr ServerHandle = IntPtr.Zero;
internal IntPtr ServerConextHandle = IntPtr.Zero;
internal IntPtr ErrorHandle = IntPtr.Zero;
internal IntPtr SessionHandle = IntPtr.Zero;
internal IntPtr StatementHandle = IntPtr.Zero;
} 以下为测试代码:
public partial class Form1 : Form
{
...... private void button1_Click(object sender, EventArgs e)
{
OciContext context = new OciContext();
int status = Oci_InitContext(context);
DebugLog.Write("初始化OCI上下文失败,返回状态: " + status);
Console.WriteLine("初始化OCI上下文失败,返回状态: " + status);
} /// <summary>
/// 初始化OCI上下文。
/// </summary>
/// <param name="context">OCI上下文。 </param>
/// <returns>执行状态。 </returns>
private int Oci_InitContext(OciContext context)
{
//创建OCI环境
int status = OciNativeMethods.OCIEnvCreate(out context.EnviromentHandle, OciNativeMethods.OCI_DEFAULT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //申请错误句柄
status = OciNativeMethods.OCIHandleAlloc(context.EnviromentHandle, out context.ErrorHandle, OciNativeMethods.OCI_HTYPE_ERROR, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //申请服务器句柄
status = OciNativeMethods.OCIHandleAlloc(context.EnviromentHandle, out context.ServerHandle, OciNativeMethods.OCI_HTYPE_SERVER, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //申请服务器上下文句柄S
status = OciNativeMethods.OCIHandleAlloc(context.EnviromentHandle, out context.ServerConextHandle, OciNativeMethods.OCI_HTYPE_SVCCTX, 0, IntPtr.Zero);
if (status != OciNativeMethods.OCI_SUCCESS) return status; //连接数据库服务器
string dblink = "ORCL";
status = OciNativeMethods.OCIServerAttach(context.ServerHandle, context.ErrorHandle, dblink, dblink.Length < < 1, OciNativeMethods.OCI_DEFAULT);
if (status != OciNativeMethods.OCI_SUCCESS)
{
Console.WriteLine("连接失败:" + Oci_GetError(context.ErrorHandle));
return status;
}
Console.WriteLine("连接成功。"); ...... return status;
} ......
} 执行到红色部分时出错,返回的状态代码为-1。
需要说明的是,我在本机上装了一个Oracle10g,SID是ORCL,tnsnames.ora文件的完整内容是:
# tnsnames.ora Network Configuration File: c:\oracle\product\10.2.0\db_1\network\admin\tnsnames.ora
# Generated by Oracle configuration tools. ORCL =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = ms-c3a782ca83be)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl)
)
) EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
) 调用OCIServerAttach失败后,通过Oci_GetError接口获取到错误信息:
ORA-12154: TNS: 无法解析指定的连接标识符。
我用PL/SQL Developer是可以登录的。请大家帮忙看看是怎么回事,急等,谢谢。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货