• C#/C++ 通过ODBC连接OceanBase Oracle租户


    概述

    近期我们项目正处于将Oracle数据库迁移到OceanBase Oracle租户模式的阶段。考虑到我们项目采用了C++和C#混合开发,并且使用了多种技术,因此存在多种数据库连接方式。然而,针对C#连接OceanBase的案例相对较少,因此我特意记录下这一过程。

    开放数据库互连(ODBC)是微软公司开放服务结构(WOSA,Windows Open Services Architecture)中有关数据库的一个组成部分,基本思想是为用户提供简单、标准、透明的数据库连接的公共编程接口,开发厂商根据 ODBC 的标准去实现底层的驱动程序,这个驱动对用户是透明的,并允许根据不同的 DBMS 采用不同的技术加以优化实现。

    驱动下载

    下载地址:https://www.oceanbase.com/softwarecenter-cloud

    根据平台类型选择驱动。

    驱动配置

    打开 ODBC 数据源管理员:在 Windows 中,按下 Windows键 + R 打开“运行”对话框,然后输入 odbcad32 并按下 Enter 键,这将打开 ODBC 数据源管理员。

     选择系统的或用户的数据源:在 ODBC 数据源管理员中,有两个选项卡:用户 DSN 和 系统 DSN。选择一个适合你的选项,通常建议选择 系统 DSN,因为它对所有用户都可用。

    添加一个新的数据源:点击 添加 按钮,然后在弹出的对话框中选择 OceanBase ODBC 2.0 Driver 数据库。

    配置数据源连接信息:在配置 OceanBase 数据库数据源时,你需要提供以下信息:

    数据源名称(DSN):为你的数据源指定一个唯一的名称。这里命名为OceanBase ODBC

    描述:提供有关此数据源的描述,以便识别它。

     TNS 服务名称:输入你要连接的 Oracle 服务的 TNS 服务名称。IP: XX.XX.XX.XX

    用户名和密码:提供用于连接到 Oracle 数据库的用户名和密码。

     UserName: 用户名@租户名#集群

    测试连接:在完成配置后,你可以点击 测试连接 按钮来验证是否能够成功连接到 OceanBase Oracle 数据库。

    注意:不通过DSN也可以连接

    C++ 代码案例

    复制代码
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    void print_error(SQLSMALLINT HandleType, SQLHANDLE Handle) {
        SQLWCHAR SQLState[6];
        SQLINTEGER NativeError;
        SQLWCHAR SQLMessage[SQL_MAX_MESSAGE_LENGTH] = { 0 };
        SQLSMALLINT TextLengthPtr;
    
        SQLGetDiagRec(HandleType, Handle, 1, SQLState, &NativeError, SQLMessage, SQL_MAX_MESSAGE_LENGTH, &TextLengthPtr);
        std::wcerr << L"[" << SQLState << L"] (" << NativeError << L") " << SQLMessage << std::endl;
    }
    
    int main() {
        // Allocate environment handle
        SQLHANDLE henv;
        SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
        SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
    
        // Allocate connection handle
        SQLHANDLE hdbc;
        SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    
        // Connection string
    
        //使用DSN
        SQLWCHAR* connectionString = (SQLWCHAR*)L"DSN=OceanBase ODBC;UID=用户名@住户名#集群;PWD=密码";
    
        //不使用DSN
        //SQLWCHAR* connectionString = (SQLWCHAR*)L"Driver={OceanBase ODBC 2.0 Driver};Server=xx.xx.xx.xx;Port=2883;Database=用户名;User=用户名@住户名#集群;Password=密码;Option=3;";
    
        // Connect to the database
        SQLRETURN retcode = SQLDriverConnect(hdbc, NULL, connectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
        if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
            std::cerr << "Error connecting to database:" << std::endl;
            print_error(SQL_HANDLE_DBC, hdbc);
            return 1;
        }
    
        std::cout << "Connected to database successfully!" << std::endl;
    
        // Allocate statement handle
        SQLHANDLE hstmt;
        SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
    
        // Execute a query
        SQLWCHAR* query = (SQLWCHAR*)L"SELECT * FROM TIERS WHERE ROWNUM <= 1;";
        retcode = SQLExecDirect(hstmt, query, SQL_NTS);
        if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) {
            std::cerr << "Error executing query:" << std::endl;
            print_error(SQL_HANDLE_STMT, hstmt);
            SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
            SQLDisconnect(hdbc);
            SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
            SQLFreeHandle(SQL_HANDLE_ENV, henv);
            return 1;
        }
    
        // Fetch and print results
        SQLCHAR name[256];
        SQLLEN nameLen;
        while (SQLFetch(hstmt) == SQL_SUCCESS) {
            SQLGetData(hstmt, 1, SQL_C_CHAR, name, sizeof(name), &nameLen);
            std::cout << "Name: " << name << std::endl;
        }
    
        // Cleanup
        SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
        SQLDisconnect(hdbc);
        SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
        SQLFreeHandle(SQL_HANDLE_ENV, henv);
    
        return 0;
    }
    复制代码

    C# 代码案例

    复制代码
    using System;
    using System.Data.Odbc;
    
    namespace ConsoleApp
    {
        internal class Program
        {
            static void Main(string[] args)
            {
                //使用DSN
                string connectionString = "DSN=OceanBase ODBC;Uid=用户名@住户名#集群;Pwd=你的密码;";
    
    
                //不使用DSN
                //string connectionString = "Driver={OceanBase ODBC 2.0 Driver};Server=xx.xx.xx.xx;Port=2883;Database=用户名;User=用户名@住户名#集群;;Password=密码;Option=3;";
                using (OdbcConnection connection = new OdbcConnection(connectionString))
                {
                    try
                    {
                        connection.Open();
                        Console.WriteLine("Connected to Oracle database!");
    
                        // Perform database operations here
    
                        string query = "SELECT *FROM TIERS WHERE ROWNUM <= 1;";
                        using (OdbcCommand command = new OdbcCommand(query, connection))
                        {
                            using (OdbcDataReader reader = command.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    int id = reader.GetInt32(0); // 假设第一列是 ID
                                    string name = reader.GetString(1); // 假设第二列是 Name
                                    Console.WriteLine($"ID: {id}, Name: {name}");
                                }
                            }
                        }
    
                        connection.Close();
                    }
    
            }
        }
    }
    复制代码

     

    NHibernate示例

    安装NHibernate

    使用NuGet包管理器安装NHibernate。你可以在Visual Studio中打开NuGet包管理器控制台,然后运行以下命令:

    Install-Package NHibernate

    这将自动下载并安装NHibernate及其所有依赖项到你的项目中。

    配置NHibernate

     

    NHibernate.cfg.xml
    复制代码
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
        <session-factory>
            <property name="connection.driver_class">NHibernate.Driver.OdbcDriverproperty>
            
            <property name="connection.connection_string">Driver={OceanBase ODBC 2.0 Driver};Server=xx.xx.xx.xx;Port=2883;Database=用户名;Uid=用户名@住户名#集群;Pwd=密码;property>
            <property name="dialect">NHibernate.Dialect.Oracle10gDialectproperty>
        session-factory>
    hibernate-configuration>
    复制代码

    配置映射类

    复制代码
    public class TestEntity
    {
        public virtual int Ident { get; set; }
    
        public virtual string Name { get; set; }
    }
    复制代码

     

    复制代码
    xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
        <class name="ConsoleApp2.TestEntity, ConsoleApp2" table="TESTENTITY">
            <id name="Ident" column="IDENT" />
            <property name="Name" column="NAME" />
            
        class>
    hibernate-mapping>
    复制代码

    查询案例

    复制代码
    using NHibernate.Cfg;
    using System;
    using System.IO;
    
    class Program
    {
        static void Main(string[] args)
        {
            string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
            var cfg = new Configuration().Configure(Path.Combine(baseDirectory, "NHibernate.cfg.xml"));
            cfg.AddFile(Path.Combine(baseDirectory, "TestEntity.xml"));
    
            var sessionFactory = cfg.BuildSessionFactory();
            using (var session = sessionFactory.OpenSession())
            {
                var query = session.CreateQuery("FROM TestEntity")
                    .SetMaxResults(10);
    
                var results = query.List();
            }
        }
    }
    复制代码

     

  • 相关阅读:
    OpenGLES:绘制一个混色旋转的3D立方体
    Cesium快速上手2-Model图元使用讲解
    写给Python社群的第9课:学一下文件处理,Python基础提高篇
    如何使用 SEGGER Embedded Studio创建库文件?
    unity使用vs进行c#代码提示,查看F12unity元代码
    Kubernetes笔记-部署安装指南
    记一次 .NET 某医院门诊软件 卡死分析
    HTTP协议和Tomcat服务器
    Oracle数据库:链接配置,包括sqlnet.ora里面的transnames.ora配置数据库标识符SID,listener暂时简单了解
    计算机操作系统 第三章:处理机调度与死锁(3)
  • 原文地址:https://www.cnblogs.com/mchao/p/18168337