Is there some way to access Sql server from z/OS mainframe and have the result in IBM 3270 terminal emulation?

StackOverflow https://stackoverflow.com/questions/2220191

Question

Is there any way (possibly cheap) to access Microsoft Sql Server from z/OS mainframe (COBOL programs) and have the result in 3270 terminal emulation?
I'm aware that 3270 is a pretty old system, but in bank CED, is still very popular.

Was it helpful?

Solution

It depends on what you are actually trying to do. My reading of your question is that you want to have a mainframe based process access an SQL Server database, and then do something with the result, probably involving a 3270 terminal.

If you can use Unix System Services, you can compile a TDS library like FreeTDS and then use a C program to do what you want with the result. If you want to get more complex, you can run the connection from the native z/OS environment by compiling the code with IBM C, SAS C or Dignus C/C++. I can recommend Dignus and I have used it to build code that interacts with other languages on z/OS. The Dignus headers and runtime library have (from memory) some FreeBSD lineage which helps to simplify porting.

Using this approach you can get a load module that you can call from some other part of your system to do the work, you can link the code with other parts of your system, or you can just submit a job and get the output.

If you want to use Java, you can use something like jTDS and write Java code to do what you need. I haven't used Java on z/OS, so I can't offer specific advice there, but I have used jTDS on other platforms and I've been happy with the result.

Update:

You can export a C function as an entry point to a load module and then call that from Cobol. The C/C++ implementation needs to deal with Cobol data structures; they are well defined and predictable so that isn't a problem. Depending on how flexible you need things to be, you could compile the query into the C code and just have a function which executed a predefined query and had an interface for retrieving the result, or you could have something more complex where the query was provided from the Cobol program.

I have used this approach to provide API functions to Adabas/Natural developers and it worked well. The Dignus compiler has a mechanism for callers to provide a handle to a runtime library so that you can manage the lifetime of the C runtime environment from the calling program.

For a C/C++ developer, that should be fairly straightforward. If your developers are all Cobol developers, things could be a bit more tricky.

The gateway approach is possible, and I'm sure there are gateway products around, but I can't recommend one. I have seen crappy ones that I wouldn't recommend, but that doesn't mean that there isn't a good one somewhere.

For completeness, I'll mention the possibility of implementing the TDS protocol in Cobol. Sounds like cruel and usual punishment, though.

OTHER TIPS

If you have 3270 terminal emulation, what terminals are you using? PC's?

One interesting hack is using a Cisco router to do on the fly 3270 to vanilla TCP conversion, and then writing a simple TCP proxy for your SQL Server procedures

Not as such - 3270 emulators are connecting to an IBM mainframe. In order to get at data from a SQL server database on a mainframe, you would have to write a program running on the mainframe that reads data from the SQL server DB. This would require you to have driver software running on the mainframe. You might be able to find a third party that makes this type of thing, but it is likely to be quite expensive.

If you need to put together a report or something combining data from a mainframe system with external data sources it may be easier to get the data off the mainframe and do the integration elsewhere - perhaps some sort of data mart.

An alternative would be to extract thd data you want from the SQL Server database and upload it to the mainframe as a flat file for processing there.

Here is a possiblity if you are writing COBOL programs that are running in CICS.

First, wrap your SQL Server database stored procedure with a web service wrapper. Look at devx.com article 28577 for an example.

After that, call your new SQL Server hosted web service using a CICS web service call.

Last use standard CICS BMS commands to present the data to the user.

Appliation Development for CICS Web Services

Just get the JDBC driver to access the MS-SQL server. You can then subclass it and use it in your Cobol program and access the database just as if you were using it from Java.

Once you get your results, you can present them via regular BMS functions.

No dirty hacks or fancy networking tricks needed. With IBM Enterprise Cobol, you really can just create a Java class and use it as you would in the Java space.

You might be able to do something I did in the past. I have written DB2 to MS-SQL COBOL programs/functions that make the MS-SQL table/view SELECT only to DB2. It involved creating a running service on a network server that would accept TCP/IP connections only from the mainframe and use the credentials passed as the user ID/PW used to access the MS-SQL table. It would then issue a select against the table/view and pass the field names list back first with the total number of rows. It would then pass each row, as tab delimited fields, back to the mainframe. The COBOL program would save the field names in a table to be used to determine which routine to use to translate each MS-SQL field to DB2. From the DB2 point of view, it looks like a function that returns fields. We have about 30 of these running. I had to create a MS-SQL describe procedure to help create the initial defines of the field transations for the COBOL program. Also had to create a COBOL program to read the describe data and create the linkage and procedure division commands. One COBOL program for each MS-SQL table/view. Here is a sample function definition. CREATE FUNCTION
TCL.BALANCING_RECON(VARCHAR(4000))
RETURNS
TABLE(
SCOMPANY CHAR(6),
PNOTENO VARCHAR(14),
PUNIT CHAR(3),
LATEFEES DEC(11,2),
FASB_4110 DEC(11,2),
FASB_4111 DEC(11,2),
USERAMOUNT1 DEC(11,2),
USERAMOUNT2 DEC(11,2),
USERFIELD1 VARCHAR(14)
)
LANGUAGE COBOL
CONTINUE AFTER FAILURE
NOT DETERMINISTIC
READS SQL DATA
EXTERNAL NAME DB2TCL02
COLLID DB2TCL02
PARAMETER STYLE SQL
CALLED ON NULL INPUT
NO EXTERNAL ACTION
DISALLOW PARALLEL
SCRATCHPAD 8000
ASUTIME LIMIT 100
STAY RESIDENT YES
PROGRAM TYPE SUB
WLM ENVIRONMENT DB2TWLM
SECURITY DB2
DBINFO
; COMMIT;
GRANT EXECUTE ON FUNCTION TCL.BALANCING_RECON TO PUBLIC;

To call the function: SELECT * FROM
TABLE (TCL.BALANCING_RECON(''
)) AS X;

You would put any MS-SQL filter commands between the quotes.

I've not been asked to update any MS-SQL data so I've not jumpped that hurdle yet. There is also a database in DB2 that keeps track of the ID/PW and server that has the started task running. This is so if the server becomes overloaded, different selects can be pushed to different servers. Response is quick, even for large tables. Timeout is the same as the 60 deadlock timeout. The transport is primarly IP based. DB2 simly sees the data as an external table reference.

As dirty hacks go, have you thought about creating a simple HTTP or TCP server that returns a .csv of the table data that you need?

This means your client only needs a simple HTTP/TCP client to access the data rather than a database client library.

In my company, we use Java for connect to Sql Server.

And a CL call this Java program :)

Very simple...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top