使用 ADO.NET 从 COBOL 连接到 MySQL 或 SQL-Server





3.00/5 (1投票)
使用 ADO.NET 连接到 MySQL 或 SQL Server 的 .NET COBOL 程序怎么样?
介绍 - 为什么?
使用 ADO.NET 连接到 MySQL 或 SQL Server 的 .NET COBOL 程序怎么样?这可能看起来有点不寻常 - 但事实证明它非常简单。更重要的是,这样做可能很有用;随着越来越多的数据存储在 MySQL 中,为什么不直接从 COBOL 与它对话呢?更重要的是,MySQL 实例不需要驻留在 Windows 机器上才能工作。我想我的目标是强调我们可以在 .NET 中做的任何事情都可以在 COBOL .NET 中完成 - 以及 - 我们可以在传统 COBOL 中做的所有事情,我们也可以在 COBOL .NET 中完成。
要使其工作,我们需要从 MySQL 网站下载并安装 MySQL 的 .NET 连接器:https://dev.mysqlserver.cn/downloads/connector/net/。
一旦我下载并安装了连接器(它会自行安装,然后将 Visual Studio 连接到它 - 真的很聪明),我需要从我的项目中引用它。一旦完成,我就可以通过 ADO.NET 引用 MySQL,就像我可以使用 MS SQL Server 一样。
此 COBOL 代码为我提供了 MySQL 连接字符串
*>> <summary>
*>> This is the MySQL version of GetSQLConnectionString.
*>> </summary>
*>> <returns></returns>
method-id. "GetMySQLConnectionString" private.
procedure division returning return-value as string..
move "database=cobol_test;server=localhost;user id=root; pwd=pickles;" to return-value.
end method "GetMySQLConnectionString".
这不好,因为我已经将连接硬编码到我的程序中。在这里没问题,因为这是一个“沙盒”。我几乎故意用不好的做法对其中的一些进行编码 - 只是为了让学习更容易。但是,请注意 Micro Focus COBOL .NET 如何支持内联文档。只需点击 *>> 并回车,它就会为你填写模板。
在 COBOL .NET 中,我们可以将每个类作为 type
引用,或者在当前类或程序的配置部分的 repository 段落中添加定义。如今,我通常只内联引用类型。部分原因是我可以处理更新的“无引号”语法。在这篇文章中,我使用了较旧的“带引号”语法,并将混合使用 repository 和内联方法。以下是示例的差异
repository.
class cls-sql-connection as "System.Data.SqlClient.SqlConnection"
class cls-mysql-connection as "MySql.Data.MySqlClient.MySqlConnection"
class cls-exception as "System.Exception".
但是,当一个类被引用的次数较少时,使用 type 就可以了
working-storage section.
dbh type "System.Data.Common.DbConnection".
通过引用,新的无引号语法(即将公开发布!)看起来像这样
working-storage section.
dbh type System.Data.Common.DbConnection.
有了这些东西,我可以做这样的事情
set sqlConnection to cls-mysql-connection::"New"()
这使得我的变量 sqlConnection
引用一个新的 "MySql.Data.MySqlClient.MySqlConnection
" 对象。由于 sqlConnection
实际上是在方法的 procedure section 中定义的,这意味着我的方法返回到 MySQL 的连接。您问什么方法 - 它在本文末尾的第二个列表中的类中!
这些列表中的其他几件事可能引起兴趣。第一个列表是我用来实例化和使用我编写的用于连接到数据库的类的程序。请注意它如何具有 try/catch 结构。如果你想知道如何在 COBOL .NET 中这样做,现在你知道了。
此外,在这个程序中,我展示了如何使用
move "SELECT * FROM junk" to command::"CommandText"
set reader to command::"ExecuteReader"()
然后一次一行地遍历记录集,直到找不到更多行为止
set hasMore to reader::"Read"()
perform until hasMore = false
set hasMore to reader::"Read"()
invoke type "Console"::"WriteLine"("Key={0}, Value='{1}'"
reader::"Item"(0) reader::"Item"(1))
end-perform
其中 hasMore
是一个 condition-value
,它与 C# 中的 bool
或 VB.NET 中的 Boolean
相同。这段代码还展示了一种方便的简写方式,可以使用 invoke type "Console"::"WriteLine"
输出到控制台。
好的 - 这是 测试程序的列表
$Set SourceFormat "FREE".
program-id. Program1 as "ADODN_Sandpit.Program1".
environment division.
configuration section.
repository.
class cls-Connector as "ADODN_Sandpit.ADOConnector".
data division.
working-storage section.
*> My little class to grab a connection to the db
01 connector cls-Connector.
*> Stores my connection
01 dbh type "System.Data.Common.DbConnection".
*> Lets me execute SQL
01 reader type "System.Data.Common.DbDataReader".
*> Holds the returned rows from a query
01 command type "System.Data.Common.DbCommand".
*> Used to check if more rows are availible
01 hasMore condition-value.
01 ex type "Exception".
procedure division.
try
set connector to cls-Connector::"new"
set dbh to connector::"ConnectMySQL"()
invoke type "Console"::"WriteLine"("Connected to test DB OK!")
*> Now we are connected - lets see if we have records in the test table
set command to dbh::"CreateCommand"()
move "SELECT * FROM junk" to command::"CommandText"
set reader to command::"ExecuteReader"()
set hasMore to reader::"Read"()
perform until hasMore = false
set hasMore to reader::"Read"()
invoke type "Console"::"WriteLine"("Key={0}, Value='{1}'"
reader::"Item"(0) reader::"Item"(1))
end-perform
catch ex
invoke type "Console"::"WriteLine"("Exception: {0}" ex::"ToString"())
end-try
goback.
end program Program1.
这是 封装了连接到 MySQL 或 SQL Server 的逻辑的类
$Set SourceFormat "FREE".
*>> <summary>
*>> A development only place holder for the logic to connect to my
*>> test database.
*>> </summary>
class-id. ADOConnector as "ADODN_Sandpit.ADOConnector".
environment division.
configuration section.
repository.
class cls-sql-connection as "System.Data.SqlClient.SqlConnection"
class cls-mysql-connection as "MySql.Data.MySqlClient.MySqlConnection"
class cls-exception as "System.Exception".
static.
working-storage section.
*> Instance data would go here - but there isn't any in this example
end static.
object.
working-storage section.
*>> <summary>
*>> Uses MSSQL connector to connect to a sql server instance using ADO.net
*>> </summary>
*>> <returns>The DbConention object</returns>
method-id. "ConnectSQL" public.
local-storage section.
01 connect string.
01 ex cls-exception.
procedure division returning sqlConnection as type "System.Data.Common.DbConnection".
set connect to self::"GetSQLConnectionString"()
invoke type "System.Console"::"WriteLine"(connect)
set sqlConnection to cls-sql-connection::"New"()
move connect to sqlConnection::"ConnectionString"
try
invoke sqlConnection::"Open"()
catch ex
invoke self::"WriteLine"(ex)
raise ex
end-try.
goback.
end method "ConnectSQL".
*>> <summary>
*>> Uses MySQL donnet connector to connect to a MySQL database.
*>> </summary>
*>> <returns>The database connection as a DbConnection object</returns>
method-id. "ConnectMySQL" public.
local-storage section.
01 connect string.
01 ex cls-exception.
procedure division returning sqlConnection as type "System.Data.Common.DbConnection".
set connect to self::"GetMySQLConnectionString"()
invoke type "Console"::"WriteLine"(connect)
set sqlConnection to cls-mysql-connection::"New"()
move connect to sqlConnection::"ConnectionString"
try
invoke sqlConnection::"Open"()
catch ex
invoke self::"WriteLine"(ex)
raise ex
end-try.
goback.
end method "ConnectMySQL".
*>> <summary>
*>> Returns a connect string for SQL Server, this should not be hard coded
*>> but in a development test bed like this, it is handy just to put the string
*>> in an easy place to find
*>> </summary>
*>> <returns></returns>
method-id. "GetSQLConnectionString" private.
procedure division returning return-value as string..
move "Data Source=(local);Initial Catalog=Northwind;Integrated Security=SSPI;"
to return-value.
end method "GetSQLConnectionString".
*>> <summary>
*>> This is the MySQL version of GetSQLConnectionString.
*>> </summary>
*>> <returns></returns>
method-id. "GetMySQLConnectionString" private.
procedure division returning return-value as string..
move "database=cobol_test;server=localhost;user id=root; pwd=dog;" to return-value.
end method "GetMySQLConnectionString".
*>> <summary>
*>> This method is really just because these are debug classes.
*>> It write info out to the console. I expect it to be canned soon.
*>> </summary>
*>> <param name="msg"></param>
method-id. "WriteLine" private.
procedure division using by value msg as object.
invoke type "Console"::"WriteLine"(msg::"ToString"())
goback.
end method "WriteLine".
end object.
end class ADOConnector.
上面的代码中也值得注意的是 COBOL 支持内联文档的方式; 例如
*>> <summary>
*>> Returns a connect string for SQL Server, this should not be hard coded
*>> but in a development test bed like this, it is handy just to put the string
*>> in an easy place to find
*>> </summary>
*>> <returns></returns>
我一直忘记把它放在我的代码中!
结论
这篇文章主要讲述了在 .NET 上使用 COBOL 的可能性和一些提示。在 Windows 平台上连接到 MySQL 和 SQL-Server 的需求量很大吗?坦率地说,我怀疑。然而,这种方法的一般化具有潜在的趣味性,因为 ADO.NET 可以访问越来越多的数据源。