如何在COBOL中编写SQLite回调 [英] How to write SQLite callback in COBOL

查看:114
本文介绍了如何在COBOL中编写SQLite回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是COBOL程序员,我的最新项目是将COBOL应用程序连接到SQLite3数据库.

I'm a COBOL programmer , and my latest project is to connect a COBOL application to a SQLite3 database.

我一直在遵循本指南,他们的解决方案正是我所需要的在我的COBOL应用程序中.我已经成功地创建,连接,插入了数据并关闭了数据库,但是当我尝试从数据库中选择数据时出现了问题.

I have been following this guide, and their solution is exactly what I would need in my COBOL application. I have successfully managed to create, connect, insert data and close the database, but the problem arises when I try to select data from the database.

在本教程中,他们使用带有双指针的回调.

In the tutorial, they use a callback with double pointers.

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
   int i;
   for(i=0; i<argc; i++){
      printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
   }
   printf("\n");
   return 0;
}

我在COBOL中的解决方案如下

My solution in COBOL is the following

   WORKING-STORAGE SECTION.
  *----------------------------------------------------------------*

   01 sqlite3-db         pointer.
   01 err_msg            pointer.
   01 sqlite             pointer.
   01 res                pointer.

   01 notused            pointer.
   01 argc               pic 99 comp-5.
   01 argv               pointer.
   01 azColName          pointer.
   01 Writefunction-Ptr  procedure-pointer.

   procedure division.
          set Writefunction-Ptr to entry "sqlite-callback".

          *>Random code.

          call "sqlite3_exec" using
             by value sqlite3-db
             by reference sqlQuery
             by value Writefunction-Ptr
             by value 0
             by reference err_msg
           returning rc
          end-call

          *>Random code.

   stop run. 

   entry "sqlite-callback" using
           by value notused
           by value argc
           by reference argv
           by reference azColName.

       display argc

       goback.
   Entry-Termination.

回调之所以起作用,是因为它被称为从数据库返回的行数,并且整数argc包含表所包含的列数.

The callback works because it is called the number of rows that is returned from the database, and the integer argc contains the number of columns that the table contains.

问题是:

COBOL中的双指针,它们如何表示?在我的解决方案中,我声明了一个指针,并使用该指针的按引用"调用回调.不知道这是否是在COBOL中表示双指针的正确方法吗?

Double pointers in COBOL, how are they represented? In my solution I declare a pointer and call the callback with "by reference" on the pointer. Don't know if this is the correct way to represent double pointers in COBOL?

如何显示azColName和argv的内容,而不仅仅是指针所指向的内存地址?

How do I display the content of the azColName and argv, and not just the memory address which the pointer points to?

我现在尝试使用SET ADDRESS OF,但是我仍然无法使用它.一定是我想念的东西.目前,我的解决方案如下:

I hove now tried to use SET ADDRESS OF, but I still don´t get it to work. Must be something i´ve missed. My solution at the moment looks like:

WORKING-STORAGE SECTION.
01 argv pointer.

Linkage Section.
01 link-area   pic x.

procedure division using link-area.

 *> RANDOM CODE

     set address of link-area to argv
     call "sqlite3_exec" using
        by value sqlite3-db
        by reference z"SELECT * FROM Cars"
        by value Writefunction-Ptr
        by value 0
        by reference err_msg
        returning rc
      end-call

 *> RANDOM CODE


entry "sqlite-callback" using
  by value notused
  by value argc
  by reference argv
  by reference azColName.

  display argc.

  if address of link-area not = null
     display "Contents of new argv: " link-area
  else
     display "empty"
  end-if

  goback.

Entry-Termination.

我得到的结果是if语句始终为false,因此显示字符串空".但是仍然将argc设置为表中的列数.

The result I get is that the if statement is always false, so the string "empty" is displayed. But still argc is set to the number of colums in the table.

可行的解决方案:

   WORKING-STORAGE SECTION.

   01 argv.
       03  firstColumn   pointer.
       03  secondColumn  pointer.
       03  thirdColumn   pointer.

   01 azColName          pointer.
   01 argc               pic 99 comp-5.
   01 notused            pointer.

   01 Writefunction-Ptr  procedure-pointer.

  *-----------------------------------------------------------------
   Linkage Section.

   01 Cars_Id       pic 9(2).
   01 Cars_Name     pic X(20).
   01 Cars_Price    pic 9(10).
  /-----------------------------------------------------------------
   procedure division.

    //code      

    set Writefunction-Ptr to entry "sqlite-callback".

          initialize sqlQuery
          move z"SELECT * FROM Cars;" to sqlQuery


          call "sqlite3_exec" using
             by value sqlite3-db
             by reference sqlQuery
             by value Writefunction-Ptr
             by value 0
             by reference err_msg
           returning rc
          end-call

    //code

    stop run.



   entry "sqlite-callback" using
           by value notused
           by value argc
           by reference argv
           by reference azColName.

       set address of Cars_Id to firstColumn
       set address of Cars_Name to secondColumn
       set address of Cars_Price to thirdColumn


       display Cars_Id "|" Cars_Name "|" Cars_Price

       goback.
   Entry-Termination.

推荐答案

我们真的需要知道您使用的编译器.

We really need to know the compiler you are using.

您的SET语句在错误的位置. argv仅在调用ENTRY时具有一个地址.在调用该条目之前,它将为二进制零或某些不可预测的垃圾.

Your SET statement is in the wrong place. argv only has an address when the ENTRY is called. Before the entry is called, it will be binary zero, or some unpredictable rubbish.

如果将SET移至ENTRY之后,则应该可以使用LINK-AREA的值. argv仍然只是一个地址,但是LINK-AREA(请给它一个更好的名称,请指向它)将指向该地址,因此将其定义为argv,然后可以使用LINK-AREA来获取该地址. argv的实际内容.

If you move the SET to after the ENTRY, you should then be able to use the value of LINK-AREA. argv will still only be an address, but LINK-AREA (give it a better name, please) will be pointing to that address, so define it as argv should be defined, and then LINK-AREA can be used to get the actual content of argv.

使用BY REFERENCE时,编译器生成代码以传递带有数据项地址的指针.

When using BY REFERENCE the compiler generates code to pass a pointer with the address of the data-item.

PROCEDURE DIVISION USINGENTRY USING上,该项目也应为引用",并且编译器生成代码以将LINKAGE SECTION定义映射到传递的地址.

On the PROCEDURE DIVISION USING or ENTRY USING the item should also be BY REFERENCE and the compiler generates code to map your LINKAGE SECTION definition to the address passed.

如果使用BY CONTENT,则类似,但是编译器在程序中获取数据的副本,并传递一个引用该指针的指针.关于仍被定义为引用"的程序"分部或条目的使用.

This is similar if you use BY CONTENT, but the compiler takes a copy of the data within your program and passes a pointer which references that instead. On the USING of the PROCEDURE DIVISION or ENTRY that is still defined as BY REFERENCE.

使用BY VALUE,编译器会传递"实际值,尽管存在一些限制,无论是标准中指定的限制还是实际编译器对标准的扩展.程序分区或条目的使用也应按值指定.

With BY VALUE the compiler "passes" the actual value, although there are limits, either those specified in the Standard or extensions to the Standard with your actual compiler. The USING of the PROCEDURE DIVISION or ENTRY should specify BY VALUE as well.

在所有使用情况下,均按引用/内容/值"进行传播,如果全部相同,则无需完全指定"BY",并且您希望使用引用",这是默认设置.

On all the USINGs, BY REFERENCE/CONTENT/VALUE are propagated, you don't need to specify BY at all if all are the same and you want BY REFERENCE, it is the default.

如果传递" POINTER(USAGE POINTER),则可以使用SET ADDRESS OF访问所指向的数据. SET ADDRESS OF项目必须位于LINKAGE SECTION中.

If you "pass" a POINTER (USAGE POINTER) then you can access the data pointed to by using SET ADDRESS OF. The SET ADDRESS OF item must be in the LINKAGE SECTION.

您还可以在SET ADDRESS OF中使用隐式指针.将地址中的a设置为b会将链接部分中映射的地址更改为b的地址,b是在程序的DATA DIVISION中定义的项(FILE SECTION以外的任何其他部分).

You can also use an implicit pointer with SET ADDRESS OF. SET ADDRESS OF a TO ADDRESS OF b will change the address mapped in the LINKAGE SECTION to the address of b, an item that is defined somewhere in your program's DATA DIVISION (any SECTION other than the FILE SECTION).

如果要查看POINTER指向的数据,请定义大小和类型正确的项目,并使用SET ADDRESS OF项目TO指针名称.

If you want to see the data pointed-to by a POINTER, define an item which has the correct size and type and use SET ADDRESS OF item TO pointer-name.

POINTER当然可以指向简单的数据项或组数据项(结构).

The POINTER can of course be pointing to a simple data-item or a group data-item (a structure).

链接部分中的所有项目都必须具有一个地址,然后才能对其进行引用.那些使用USING的地址由编译器提供寻址能力(并且编译器假定传递了正确数量的地址/项目).所有其他链接节项都必须具有可寻址性,该可寻址性是通过使用CALL的SET ADDRESS OF或通过传递ADDRESS OF并通过CALLed程序设置地址来建立的.

All items in the LINKAGE SECTION must have an address before they are referenced. Those on a USING are given addressability by the compiler (and the compiler assumes that the correct number of addresses/items are passed). All other LINKAGE SECTION items must have addressability established by SET ADDRESS OF or by passing ADDRESS OF in the USING of a CALL and having the CALLed program set the address.

这篇关于如何在COBOL中编写SQLite回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆