使用ODBC和SQL使用Cobol连接到Quick Books Database

时间:2015-12-11 16:21:32

标签: database odbc quickbooks cobol embedded-sql

我们正试图打开与QB DB的连接并从中获取任何数据。我们设法用C#实现了它,但是转换为CoBOL(一种对我们来说很陌生的语言)证明是非常困难的。这是C#代码:

class Program {
        static void Main(string[] args)
        {
            var odbcConnection = new OdbcConnection("DSN=QuickBooks Data;DFQ=C:\\Users\\Public\\Documents\\Intuit\\QuickBooks\\Company Files\\" +
                                                "ourQuickBooksFile.qbw;OLE DB Services=-2;OpenMode=S");
            odbcConnection.Open();

            var odbcDataAdapter = new OdbcDataAdapter("SELECT ListID, FullName, CompanyName FROM Customer", odbcConnection);
            var dataSet = new DataSet();

            odbcDataAdapter.Fill(dataSet);

            DataRowCollection dataRowCollection = dataSet.Tables[0].Rows;
            foreach (DataRow dataRow in dataRowCollection)
            {
                Console.WriteLine(dataRow["ListID"] + " " + dataRow["FullName"] + " " + dataRow["CompanyName"]);    
            }
            Console.ReadLine();
            odbcConnection.Close();

        }
    }

我们对替代方法持开放态度,但COBOL部分是必不可少的。

我们正在使用Windows 10和GnuCOBOL。

2 个答案:

答案 0 :(得分:3)

这里有一些关于ODBC访问的GnuCOBOL常见问题解答中的一些框架代码,而不只是发布链接,(在底部,你需要它来掌握编译器选项)使用Sergey Kashyrin的esqlOC预处理器。

   IDENTIFICATION DIVISION.
   PROGRAM-ID. esqlOCGetStart1.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   EXEC SQL
     BEGIN DECLARE SECTION
   END-EXEC.
   01  HOSTVARS.
       05 BUFFER               PIC X(1024).
       05 hVarD                PIC S9(5)V99.
       05 hVarC                PIC X(50).
       05 hVarN                PIC 9(12).
   EXEC SQL
      END DECLARE SECTION
   END-EXEC.
   PROCEDURE DIVISION.
   MAIN SECTION.
  *-----------------------------------------------------------------*
  * CONNECT TO THE DATABASE
  * also possible with DSN: 'youruser/yourpasswd@yourODBC_DSN'
  *-----------------------------------------------------------------*
     STRING 'DRIVER={MySQL ODBC 5.2w Driver};'
            'SERVER=localhost;'
            'PORT=3306;'
            'DATABASE=test;'
            'USER=youruser;'
            'PASSWORD=yourpasswd;'
  * example for DB specific ODBC parameter:
  *   no compressed MySQL connection (would be the DEFAULT anyway)
            'COMRESSED_PROTO=0;'
       INTO BUFFER.
     EXEC SQL
       CONNECT TO :BUFFER
     END-EXEC.
     PERFORM SQLSTATE-CHECK.
  *-----------------------------------------------------------------*
  * CREATE  TABLEs
  *-----------------------------------------------------------------*
  * TESTPERSON
     MOVE SPACES TO BUFFER.
     STRING
       'CREATE TABLE TESTPERSON('
         'ID DECIMAL(12,0), '
         'NAME CHAR(50) NOT NULL, '
         'PRIMARY KEY (ID))'
       INTO BUFFER.
     EXEC SQL
       EXECUTE IMMEDIATE  :BUFFER
     END-EXEC
     IF SQLSTATE='42S01'
       DISPLAY ' Table TESTPERSON already exists.'
     ELSE
       PERFORM SQLSTATE-CHECK
       DISPLAY ' created Table TESTPERSON'
       PERFORM INSDATAPERSON.
  * TESTGAME
     MOVE SPACES TO BUFFER.
     STRING
       'CREATE TABLE TESTGAME('
         'ID DECIMAL(12,0), '
         'NAME CHAR(50) NOT NULL, '
         'PRIMARY KEY (ID))'
       INTO BUFFER.
     EXEC SQL
       EXECUTE IMMEDIATE  :BUFFER
     END-EXEC
     IF SQLSTATE='42S01'
       DISPLAY ' Table TESTGAME already exists.'
     ELSE
       PERFORM SQLSTATE-CHECK
       DISPLAY ' created Table TESTGAME'
       PERFORM INSDATAGAME.
  * TESTPOINTS
     MOVE SPACES TO BUFFER.
     STRING
       'CREATE TABLE TESTPOINTS('
         'PERSONID DECIMAL(12,0), '
         'GAMEID DECIMAL(12,0), '
         'POINTS DECIMAL(6,2), '
         'CONSTRAINT POINTS_CONSTRAINT1 FOREIGN '
           'KEY (PERSONID) REFERENCES TESTPERSON(ID), '
         'CONSTRAINT POINTS_CONSTRAINT2 FOREIGN '
           'KEY (GAMEID) REFERENCES TESTGAME(ID),'
         'PRIMARY KEY (PERSONID, GAMEID))'
       INTO BUFFER.
     EXEC SQL
       EXECUTE IMMEDIATE  :BUFFER
     END-EXEC
     IF SQLSTATE='42S01'
       DISPLAY ' Table TESTPOINTS already exists.'
     ELSE
       PERFORM SQLSTATE-CHECK
       DISPLAY ' created Table TESTPOINTS'
       PERFORM INSDATAPOINTS.
  *-----------------------------------------------------------------*
  * SELECT SUM of POINTS for persons >1
  *-----------------------------------------------------------------*
     EXEC SQL
       SELECT
         SUM(POINTS)
       INTO
         :hVarD
       FROM
         TESTPERSON, TESTPOINTS
       WHERE PERSONID>1 AND PERSONID=ID
     END-EXEC
     PERFORM SQLSTATE-CHECK
     IF SQLCODE NOT = 100
       DISPLAY 'SELECTED '
       DISPLAY '  SUM of POINTS for persons >1 ' hVarD
     ELSE
       DISPLAY ' No points found'
     END-IF.
  *-----------------------------------------------------------------*
  * SELECT ALL with CURSORS
  *-----------------------------------------------------------------*
     EXEC SQL
       DECLARE CUR_ALL CURSOR FOR
       SELECT
         TESTPERSON.NAME,
         POINTS
       FROM
         TESTPERSON, TESTPOINTS
       WHERE PERSONID=ID
     END-EXEC
     PERFORM SQLSTATE-CHECK
     EXEC SQL
       OPEN CUR_ALL
     END-EXEC
     PERFORM SQLSTATE-CHECK
     PERFORM UNTIL SQLCODE = 100
       EXEC SQL
         FETCH CUR_ALL
         INTO
           :hVarC,
           :hVarD
       END-EXEC
       PERFORM SQLSTATE-CHECK
       IF SQLCODE NOT = 100
         DISPLAY 'FETCHED '
         DISPLAY '  person ' hVarC ' points: ' hVarD
       ELSE
         DISPLAY ' No points found'
       END-IF
     END-PERFORM.
  *-----------------------------------------------------------------*
  * DROP  TABLEs
  *-----------------------------------------------------------------*
  *   MOVE 'DROP TABLE TESTPOINTS' TO BUFFER.
  *   EXEC SQL
  *     EXECUTE IMMEDIATE  :BUFFER
  *   END-EXEC
  *   PERFORM SQLSTATE-CHECK.
  *   MOVE 'DROP TABLE TESTGAME' TO BUFFER.
  *   EXEC SQL
  *     EXECUTE IMMEDIATE  :BUFFER
  *   END-EXEC
  *   PERFORM SQLSTATE-CHECK.
  *   MOVE 'DROP TABLE TESTPERSON' TO BUFFER.
  *   EXEC SQL
  *     EXECUTE IMMEDIATE  :BUFFER
  *   END-EXEC
  *   PERFORM SQLSTATE-CHECK.
  *   DISPLAY ' dropped Tables '
  *-----------------------------------------------------------------*
  * COMMIT CHANGES
  *-----------------------------------------------------------------*
     EXEC SQL
       COMMIT
     END-EXEC.
     PERFORM SQLSTATE-CHECK.
  *-----------------------------------------------------------------*
  * DISCONNECT FROM THE DATABASE
  *-----------------------------------------------------------------*
     EXEC SQL
       CONNECT RESET
     END-EXEC.
     PERFORM SQLSTATE-CHECK.
     STOP RUN.
     .
  *-----------------------------------------------------------------*
  * CHECK SQLSTATE AND DISPLAY ERRORS IF ANY
  *-----------------------------------------------------------------*
   SQLSTATE-CHECK SECTION.
       IF SQLCODE < 0
                  DISPLAY 'SQLSTATE='  SQLSTATE,
                          ', SQLCODE=' SQLCODE
          IF SQLERRML > 0
             DISPLAY 'SQL Error message:' SQLERRMC(1:SQLERRML)
          END-IF
          MOVE SQLCODE TO RETURN-CODE
          STOP RUN
       ELSE IF SQLCODE > 0 AND NOT = 100
                  DISPLAY 'SQLSTATE='  SQLSTATE,
                          ', SQLCODE=' SQLCODE
          IF SQLERRML > 0
             DISPLAY 'SQL Warning message:' SQLERRMC(1:SQLERRML)
          END-IF
       END-IF.
       .
   INSDATAPERSON SECTION.
  *-----------------------------------------------------------------*
  * INSERT Data
  *-----------------------------------------------------------------*
  * TESTPERSON
     MOVE 0 TO hVarN.
     PERFORM UNTIL hVarN > 2
       COMPUTE hVarN = hVarN + 1
       STRING 'Testpers '
              hVarN
         INTO hVarC
       EXEC SQL
        INSERT INTO TESTPERSON SET
         ID=:hVarN,
         NAME=:hVarC
       END-EXEC
       PERFORM SQLSTATE-CHECK
       DISPLAY 'INSERTED '
       DISPLAY '  Person ' hVarN ' NAME ' hVarC
     END-PERFORM.
   INSDATAGAME SECTION.
  * TESTGAME
     MOVE 0 TO hVarN.
     PERFORM UNTIL hVarN > 3
       COMPUTE hVarN = hVarN + 1
       STRING 'Testgame '
              hVarN
         INTO hVarC
       EXEC SQL
        INSERT INTO TESTGAME SET
         ID=:hVarN,
         NAME=:hVarC
       END-EXEC
       PERFORM SQLSTATE-CHECK
       DISPLAY 'INSERTED '
       DISPLAY '  Game ' hVarN ' NAME ' hVarC
     END-PERFORM.
   INSDATAPOINTS SECTION.
  * TESTPOINTS
     MOVE 0 TO hVarN.
     MOVE 0 TO hVarD.
     PERFORM UNTIL hVarN > 2
       COMPUTE hVarN = hVarN + 1
       COMPUTE hVarD = hVarN + 0.75
       EXEC SQL
        INSERT INTO TESTPOINTS SET
         PERSONID=:hVarN,
         GAMEID=:hVarN,
         POINTS=:hVarD
       END-EXEC
       PERFORM SQLSTATE-CHECK
       DISPLAY 'INSERTED '
       DISPLAY '  POINTS for person/game ' hVarN ' : ' hVarD
     END-PERFORM.

然后预处理

esqlOC.exe -static -o c:\Temp\esqlOCGetStart1.cob c:\Temp\esqlOCGetStart1.sqb

然后编译

SET OC_RUNTIME=c:\OpenCobol_bin
SET esqlOC_RUNTIME=c:\esqlOC\release
SET COB_CFLAGS=-I %OC_RUNTIME%
SET COB_LIBS=%OC_RUNTIME%\libcob.lib %OC_RUNTIME%\mpir.lib %esqlOC_RUNTIME%\ocsql.lib
SET COB_CONFIG_DIR=%OC_RUNTIME%\config\
set PATH=C:\WINDOWS\system32;%OC_RUNTIME%
call "%PROGRAMFILES%\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"
%OC_RUNTIME%\cobc.exe -fixed -v -x -static -o c:\Temp\esqlOCGetStart1.exe c:\Temp\esqlOCGetStart1.cob

然后运行

SET OC_RUNTIME=c:\OpenCobol_bin
SET esqlOC_RUNTIME=c:\esqlOC\release
set PATH=%OC_RUNTIME%;%esqlOC_RUNTIME%
c:\Temp\esqlOCGetStart1.exe

当然,您的详细信息会有所不同。更多信息,请访问

http://open-cobol.sourceforge.net/faq/#getting-started-with-esqloc

答案 1 :(得分:1)

您没有提到您的Cobol所在的编译器/操作系统。如果您使用的是IBM的Enterprise Cobol,那么您可以使用C#代码(这实际上只是Java的一对一翻译)并将其扩展到Cobol程序中。

或者因为你显然是一个.NET商店,你可以使用.NET风格的Cobol,只需扩展你上面的C#代码。

但是如果没有关于你的环境的更多细节,很难给你一个具体的答案。