OTL(4.0) Frequently Asked Questions经典问答(2010.4.10更新)

来源:互联网 发布:苹果笔记本安装软件 编辑:程序博客网 时间:2024/05/18 08:11

原文地址:http://otl.sourceforge.net/otl3_faq.htm

   请将疑问及评论发送至:skuchin@gmail.com

 

OTL: OTL是如何处理NULL的?

  • 调用 otl_stream::is_null()检查从数据流(stream)中读取的是否为空值.
  • 利用模板类 otl_value<T>.
  • 如果有必要将读出来为空的变量值设置为某一值(对于输出值为NULL,OTL在默认情况下对输出缓冲区不作任何操作的)下面的宏可以做到:
    1. OTL_DEFAULT_NUMERIC_NULL_TO_VAL
    2. OTL_DEFAULT_DATETIME_NULL_TO_VAL
    3. OTL_DEFAULT_STRING_NULL_TO_VAL
    4. OTL_DEFAULT_CHAR_NULL_TO_VAL
    5. OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL

    OTL: 为什么OTL不支持T-SQL存储过程中的INSERT,UPDATE,DELETE指令?

    T-SQL存储过程中的INSERT/UPDATE/DELETE指令返回所处理过的行数(RPC),当使用这种OTL/C++代码时,这些行数(RPCs)作为独立的结果集通过微软的MS SQL Native Client(SNAC)返回给调用者.OTL不会处理这些RPC的结果集,因此使用者在存储过程中需要用"SET NOCOUNT ON"指令来关闭这个功能(即不让返回这些结果集--译著),例如:

        CREATE PROCEDURE my_proc
        ...
        AS
        SET NOCOUNT ON
        ...


    问 OTL:如何插入或更新类型为NVARCHAR/NCHAR且数量超过2000的字段的值?

    所有版本的MS SQL ODBC/Natie Client(包括MS SQL 2008)都有一个数量的限制:对于OTL的类型变量:v<char[XXX]>,如果定义了#define OTL_UNICODE并且将这个变量与一个类型为NVARCHAR/NCHAR的字段绑定,这个数量只限于2000个UTF-16类型的字符.也就是说如果定义变量为:<char[2002]>,MS SQL 2005将会曝出如下的错误提示:

    [Microsoft][SQL Native Client]Invalid precision value

    同样情形,MS SQL 2008的错误信息则更加详细:

    [Microsoft][SQL Server Native Client 10.0][SQL Server]The size (XXX) given to the parameter '@PN' exceeds the maximum allowed (4000).

    在MSDN的网站上我还没找到任何对这个错位消息的解释,如果谁找到了相关的网页,请告我,我会将这个URL附在本答案后面.

    如果有需要去insert / update 类型为NVACHAR / NCHAR且数量超过2000的字段,可以用:v<varchar_long>来代替 :v<char[XXX]>.可以将otl_long_unicode_string和:v<varchar_long>配合使用,例如:

    ......

    create table test_tab(f1 int, f2 nvarchar(4000));
    ......
     db.set_max_long_size(4000); // set the maximum varchar long to 4000 characters
     otl_stream o(3, // buffer size should can be > 1
                  "insert into test_tab values(:f1<int>,:f2<varchar_long>)",
                  db // connect object
                 );

     otl_long_unicode_string f2(4000);
     for(int i=1;i<=5;++i){
      o<<i;
      for(int j=0;j<4000;++j)
        f2[j]=...;
      f2.set_len(4000);
      o<<f2;
     }
    除了otl_long_unicode_string, std::wstring也可以配合varchar_long使用,类似的例子 368.

     

    问 OTL:MS SQL Server为什么不支持带绑定变量的嵌套查询?

  • 在你打开嵌套查询的数据流时,尝试在otl_connect参数后面加参数otl_implicit_select:
              otl_stream s(1,
                  "select dt from "
                  "  (select  "
                  "     dateadd(day, :v<int>, getdate() "
                  "  )dt ) xt ",
                  db, // connect object
                  otl_implicit_select
                 );

            问题就出现了:函数SQLPrepare() 没有返回任何查询输出列的指示器(抛出一个OTL异常:Column: 0<UNKNOWN>),看起来就像嵌套查询指令被转换为一个临时的存储过程,也就是说你必须指明它是一个存储过程,并且显式的返回一个结果集。我不知道数据库系统为什么这么做,可能是一种性能优化技术。

     

    问 OTL:当我再MySQL中的某个表中插入一个新的记录时,我却查询不到他,出什么问题了?

    当你在一个otl_stream中使用预设置好的SELECT指令,并且持续重复执行这个指令来得到新记录时,每次数据序列取出完毕后你都必须进行提交操作(调用otl_connect::commit()).这个提交操作让你的MySQL服务器知道你当前的只读事务已经执行完毕,服务器就可以开始一个新的事务了,这样最近插入数据库的那条记录才能通过SELECT指令展现出来.换句话说,你需要提交你的SELECT指令才能看到新插入的记录.

     

    问:我们如何才能不通过ODBC数据源而直接访问数据库?

    请参考网站。

     

    问:OTL是线程安全的吗?

    OTL没有使用任何互斥锁和零临区。如果每一个线程都拥有自己的otl_connect 对象,那么就没有必要使用互斥锁。如果在多个线程中共享数据库的连接,那么对OTL调用进行同步控制就是开发者的责任了。通常,数据库的APIs是不保证线程安全的。otl_connect::otl_initialize传递一个标志位到数据库API,仅仅是为了让API知道程序再多线程模式上运行的。

     

    问:OTL:OTL能在SQLite上运行吗?

    是的OTL/ODBC 能在SQLite上运行,详情请看考下面的例子。

     

    问:OTL:支持Oracle 10g或者11g吗?

    是的,使用宏 #define OTL_ORA10G, OTL_ORA10G_R2, 或者OTL_ORA11G。

     

    问:OTL:支持 SAP DB吗?

    是的,OTL/ODBC能在SAP DB上运行,更多的详情,请参考SAP DB的 例子

     

    问:OTL:支持PL/SQL中的CLOBs/BLOBs吗?

    答案是:依据具体的情况而定.你需要时刻牢记要把CLOB/BLOB看成PL/SQL的一个数据类型:一个大对象的定位器,而不是一个值.这就是说,这个对象本身首要要被创建,这个定位器需要从数据库中得到并传递给C++,只有这样这个定位器才能传到PL/SQL.也可以参考代码示例 378.

     

    问:OTL:支持Unicode吗?

    是的详情请看考OTL示例和参考手册。

     

    问:OTL:支持Oracle 9i吗?

    是的,从4.0.0版本开始,OTl引进了宏#define OTL_ORA9I,这就意味着它支持Oracle 9i。OTL 4.0.0本身就不再是OTL_ORA8I的同义词,但是在随后的发行版本里,当OTL开始使用OCI9独有的特性时,就必须使用宏OTL_ORA9I。详情请参考"what's new in OTL 4"。

     

    问:OTL:支持Interbase 6.x吗?
    是的,从4.0.0版本开始,OTl就支持Interbase开源的ODBC驱动。详情请参考"what's new in OTL 4"。

     

    问:OTL:支持PostgreSQL 7.x / 8.x吗?
    是的,从4.0.0版本开始,OTL通过ODBC支持PostgreSQL 7.x / 8.x。详情请参考"what's new in OTL 4"。

     

    问:OTL:支持DB2, Call Level Interface (CLI)?吗?
    是的,从3.2.7版本开始,OTl新加入了一味香料:OTL/DB2-CLI. OTL/DB2-CLI使用DB2的原生数据库API:Call Level Interface。OTL/DB2-CLI 99.5%的兼容于ODBC 3.x的规范及其其扩展。OTL头文件中就包含CLI原生的头文件,并且可以在Windows或者是Unix(主要是AIX)平台上使用DB2-CLI的原生对象库。

     

    问:OTL/ODBC: 支持MyODBC/MySQL吗?
    是的, 从3.2.4版本开始,OTL/ODBC就兼容MyODBC。获取更多MyODBC相关细节请参考MyODBC for MySQL.。宏定义#define OTL_ODBC_MYSQL 应该和MySQL默认的字段类型结合使用,因为在这种情形下OTL关闭了ODBC函数调用的事务性。如果想在MyODBC3.5中使用了InnoDB字段类型,就应该使用宏定义#define OTL_ODBC

     

    问:OTL/OCI8能和XA-connectivity一起工作吗?
    是的,当一个XA类型的连接建立后,为了获得与OCI8相兼容的环境和上下文服务句柄,xaoEnv()和xaoSvcCtx()函数就应该被调用。此后otl_connect::rlogon() 才能利用这个句柄来创建一个OTL连接。rlogon()与Pro*C 8.x相结合使用的用法类似。如何使用 rlogon() 这种类型的函数,详情请看例子59

     

    问:支持C++ string(std::string)吗?如何再OTL中整合Standard Template Library (STL)?
    OTL3.2.0以及更高的版本支持std::string(请看例子72, 73, 74),当然OTL也支持遵从STL的流迭代器otl_input_iterator, otl_output_iterator

     

    问:在任何情况下,OTL支持哪些主流的C++编译器?

    • Sun C++ Workshop 6.x and higher
    • GNU C++ 3.3.x and higher
    • VC++ 6.0 and higher
    • HP ANSI C++ (aCC) 1.x
    • AIX, Visual Age C++ 6.x and higher
    • Borland C++ 5.x
    • Intel C++ 7.0, 8.0, 9.x (Windows, Linux)

    为了完善这些列表,如果你所使用的编译器不再上述列表中,欢迎将你的C++编译器名称发邮件给我。

     

    问:有什么方法可以读/写大的BLOB而不用在内存中分配大的缓冲区?
    OTL3.1.4为Oracle 8 CLOBs/BLOBs支持stream mode,更多详情请看例子56, 57

     

    问:有什么方法可以调用将PL/SQL表作为参数的存储过程?
    OTL3.1通过 otl_streams 和 special template data containers支持PL/SQL表,更多详情请看例子 49, 50, 51, 52

     

    问:你将会继续通过邮件传递你的代码,或者有意将你的代码存放在你的网站上?
    从现在开始,OTL头文件可以用下载的方式获得。

     

    问:就我们所关心的值为NULL的问题,Large Objects (LOBs)和其他类型在行为方面有什么不同?

    详情请参考 "Large Objects and NULLs" 。

     

    问:怎样从 otl_stream中读取/写入时间日期信息?

    答案是利用otl_datetime数据容器,它是在OTL 3.1.26中引进的,详情参考示例38, 39, 40。最基本的:Oracle DATE或者是MS SQL Server DATETIME能用otl_datetime类型的变量来读/写。

     

    问:在SQL指令执行完成后,我们如何获得处理的行数?

    函数 direct_exec() 返回一个long int值,当这个值>=0时,即为SQL指令所连续处理的行数,同样otl_stream::get_rpc() 也返回一个long int值,用来指示处理过的行数。处理计数只在INSERT, UPDATE,和DELETE指令中定义.SELECT指令的RPC(row processed counts)就是获取的行数.对于其他SQL指令,PL/SQL块,存储过程调用,这个计数总是0 。