将 COBOL 数据转换为 SQL 服务器
Convert COBOL data to SQL Server
我们从 COBOL 接收数据如下,并转换到 SQL 服务器。我已经关注了这个link
并创建了 SSIS 包。但是,在将某些数据从 COBOL 转换为 SQL.
时,我遇到了问题
我将输入列标记为字节,将输出列标记为数字数据 10 和精度 2
1.Tried 在 SQL
中将列创建为 Decimal(10,2)
2.Tried 它具有 SQL COBOL 日期数据类型
程序包成功运行但未填充数据。
data layout
CONTRACT-SIZE pic S9(9)V99 COMP-3
DIV-REC-DATE-LOBO PIC 9(0007) COMP-3
PAR-DATE PIC S9(0007) COMP-3
BID-PRICE PIC S9(0005)V9(2) COMP-3
尝试使用以下函数解包、翻译、COBOLZonedPicToDecimal
Public Function Translate(ByVal str As String, sConversionTable As String) As String
Dim Temp As String, I As Int32
Temp = Space(Len(str))
For I = 1 To Len(str)
Mid(Temp, I, 1) = Mid(sConversionTable, Asc(Mid(str, I, 1)) + 1, 1)
Next
Translate = Temp
End Function
Private Function Unpack(ByVal bPacked As Byte(), ByVal iDecimalPlaces As Integer) As Decimal
Dim i As Integer
Dim HiNibble As Byte
Dim LoNibble As Byte
Dim dResult As Decimal = 0
For i = 0 To bPacked.Length - 2
UnpackNibblesToBytes(bPacked(i), LoNibble, HiNibble)
dResult = Convert.ToDecimal(dResult * 10 ^ 2I + HiNibble * 10 + LoNibble)
Next
UnpackNibblesToBytes(bPacked(bPacked.Length - 1), LoNibble, HiNibble)
dResult = dResult * 10 + HiNibble
If LoNibble = &HD& Then
dResult = -dResult
End If
Unpack = Convert.ToDecimal(dResult * 10 ^ (-iDecimalPlaces))
End Function
Private Sub UnpackNibblesToBytes(ByVal InputNibbles As Byte, ByRef LoNibble As Byte, ByRef HiNibble As Byte)
LoNibble = (Me.F And InputNibbles)
HiNibble = ((Me.F0 And InputNibbles) >> 4)
End Sub
Public Function DecimalToCOBOLZonedPic(ByVal dNumber As Decimal, ByVal iPadLength As Integer, ByVal iDecimalPlaces As Integer, ByVal bModifiedZoned As Boolean) As String
Dim isNegative As Boolean = False
Dim strNumber As String
Dim sPositive As String = "{ABCDEFGHI"
Dim sNegativeMod As String = "}JKLMNOPQR"
Dim sNegativeStrict As String = "pqrstuvwxy"
' Determine the sign
If dNumber < 0 Then
isNegative = True
dNumber = -dNumber
End If
dNumber = Convert.ToDecimal(dNumber * (10 ^ iDecimalPlaces))
strNumber = dNumber.ToString
If strNumber.IndexOf(".") > -1 Then
' Truncate remaining decimal places
strNumber = strNumber.Substring(0, strNumber.IndexOf("."))
End If
' Pad with leading zeros
If strNumber.Length < iPadLength Then
strNumber = strNumber.PadLeft(iPadLength, "0"c)
End If
Dim lastDigit As Integer = Convert.ToInt32(strNumber.Substring(strNumber.Length - 1, 1))
If bModifiedZoned Then
If isNegative Then
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeMod.Substring(lastDigit, 1).ToString
Else
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sPositive.Substring(lastDigit, 1).ToString
End If
Else
If isNegative Then
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeStrict.Substring(lastDigit, 1).ToString
End If
End If
Return strNumber
End Function
Public Function COBOLZonedPicToDecimal(ByVal strNumber As String, ByVal decimalPlaces As Integer) As Decimal
Dim sZoneChar As String
Dim convertedNumber As Decimal
Dim sPositive As String = "{ABCDEFGHI"
Dim sNegativeMod As String = "}JKLMNOPQR"
Dim sNegativeStrict As String = "pqrstuvwxy"
strNumber = strNumber.Trim
If strNumber = "" Then
Return 0
End If
sZoneChar = strNumber.Substring(strNumber.Length - 1)
Select Case True
Case sPositive.IndexOf(sZoneChar) > -1
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sPositive.IndexOf(sZoneChar)
convertedNumber = Convert.ToDecimal(strNumber)
Case sNegativeMod.IndexOf(sZoneChar) > -1
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeMod.IndexOf(sZoneChar)
convertedNumber = -Convert.ToDecimal(strNumber)
Case sNegativeStrict.IndexOf(sZoneChar) > -1
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeStrict.IndexOf(sZoneChar)
convertedNumber = -Convert.ToDecimal(strNumber)
Case Else
convertedNumber = Convert.ToDecimal(strNumber)
End Select
Return Convert.ToDecimal(convertedNumber / (10 ^ decimalPlaces))
End Function
当前文件
0x0200EAA4 转换为 EBCDIC 是 x0200529F,这是一个有效的 comp-3 值 (2020-May-29)。
运行 对二进制 EBCDIC 文件(如此文件)的 ascii 转换会损坏 文件
不要尝试处理当前文件。
解决方案
在源计算机(大型机??)上将文件转换为文本,transmit/translate 文件
如果处理 Mainframe Cobol 文件,请查看 cb2xml。它将 Cobol Copybook 转换为 Xml 文件(并计算位置/长度)。 Xml可以处理多种语言。
在源计算上转换为固定长度(可能已经是固定长度)并传输
作为 EBCDIC 文件。该文件中不会有任何回车 return 换行符。
您需要将其作为 EBCDIC 文件进行处理。
如果可以
- 运行 java
- 获取 Cobol Copybook
- Cobol copybook没有重新定义
像CobolToCsv这样的东西可以将文件从Cobol-Ebcdic转换成Ascii-Csv文件
EBCDIC
有多个EBCDIC字符集Cp037/IBM037是US EBCDIC; CP273/IBM273 是德语 EBCDIC,您需要找出正在使用的 EBCDIC 方言
注:CP037代表编码页037
大型机固定宽度
主机固定宽度,所有记录都是相同长度并且有
没有 Carriage Return / Line Feed 字符。
对于具有 26 字节记录的文件,它是
<-- 26 bytes --><-- 26 bytes --> ... <-- 26 bytes -->
cb2xml
cb2xml 会将 Cobol Copybook 转换为 xml。这允许在大多数现代语言中对 Cobol 数据进行通用处理
cb2xml 将转换
01 Location-Record.
03 Record-Type pic xx.
03 location occurs 10.
05 DC-Number pic 9(4).
05 Pack-Quantity pic 9(8).
到
<item display-length="122" level="01" name="Location-Record" position="1" storage-length="122">
<item display-length="2" level="03" name="Record-Type" picture="xx" position="1" storage-length="2"/>
<item display-length="12" level="03" name="location" occurs="10" position="3" storage-length="12">
<item display-length="4" level="05" name="DC-Number" numeric="true" picture="9(4)" position="3" storage-length="4"/>
<item display-length="8" level="05" name="Pack-Quantity" numeric="true" picture="9(8)" position="7" storage-length="8"/>
</item>
</item>
我们从 COBOL 接收数据如下,并转换到 SQL 服务器。我已经关注了这个link
并创建了 SSIS 包。但是,在将某些数据从 COBOL 转换为 SQL.
时,我遇到了问题我将输入列标记为字节,将输出列标记为数字数据 10 和精度 2
1.Tried 在 SQL
中将列创建为 Decimal(10,2)
2.Tried 它具有 SQL COBOL 日期数据类型
程序包成功运行但未填充数据。 data layout
CONTRACT-SIZE pic S9(9)V99 COMP-3
DIV-REC-DATE-LOBO PIC 9(0007) COMP-3
PAR-DATE PIC S9(0007) COMP-3
BID-PRICE PIC S9(0005)V9(2) COMP-3
尝试使用以下函数解包、翻译、COBOLZonedPicToDecimal
Public Function Translate(ByVal str As String, sConversionTable As String) As String
Dim Temp As String, I As Int32
Temp = Space(Len(str))
For I = 1 To Len(str)
Mid(Temp, I, 1) = Mid(sConversionTable, Asc(Mid(str, I, 1)) + 1, 1)
Next
Translate = Temp
End Function
Private Function Unpack(ByVal bPacked As Byte(), ByVal iDecimalPlaces As Integer) As Decimal
Dim i As Integer
Dim HiNibble As Byte
Dim LoNibble As Byte
Dim dResult As Decimal = 0
For i = 0 To bPacked.Length - 2
UnpackNibblesToBytes(bPacked(i), LoNibble, HiNibble)
dResult = Convert.ToDecimal(dResult * 10 ^ 2I + HiNibble * 10 + LoNibble)
Next
UnpackNibblesToBytes(bPacked(bPacked.Length - 1), LoNibble, HiNibble)
dResult = dResult * 10 + HiNibble
If LoNibble = &HD& Then
dResult = -dResult
End If
Unpack = Convert.ToDecimal(dResult * 10 ^ (-iDecimalPlaces))
End Function
Private Sub UnpackNibblesToBytes(ByVal InputNibbles As Byte, ByRef LoNibble As Byte, ByRef HiNibble As Byte)
LoNibble = (Me.F And InputNibbles)
HiNibble = ((Me.F0 And InputNibbles) >> 4)
End Sub
Public Function DecimalToCOBOLZonedPic(ByVal dNumber As Decimal, ByVal iPadLength As Integer, ByVal iDecimalPlaces As Integer, ByVal bModifiedZoned As Boolean) As String
Dim isNegative As Boolean = False
Dim strNumber As String
Dim sPositive As String = "{ABCDEFGHI"
Dim sNegativeMod As String = "}JKLMNOPQR"
Dim sNegativeStrict As String = "pqrstuvwxy"
' Determine the sign
If dNumber < 0 Then
isNegative = True
dNumber = -dNumber
End If
dNumber = Convert.ToDecimal(dNumber * (10 ^ iDecimalPlaces))
strNumber = dNumber.ToString
If strNumber.IndexOf(".") > -1 Then
' Truncate remaining decimal places
strNumber = strNumber.Substring(0, strNumber.IndexOf("."))
End If
' Pad with leading zeros
If strNumber.Length < iPadLength Then
strNumber = strNumber.PadLeft(iPadLength, "0"c)
End If
Dim lastDigit As Integer = Convert.ToInt32(strNumber.Substring(strNumber.Length - 1, 1))
If bModifiedZoned Then
If isNegative Then
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeMod.Substring(lastDigit, 1).ToString
Else
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sPositive.Substring(lastDigit, 1).ToString
End If
Else
If isNegative Then
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeStrict.Substring(lastDigit, 1).ToString
End If
End If
Return strNumber
End Function
Public Function COBOLZonedPicToDecimal(ByVal strNumber As String, ByVal decimalPlaces As Integer) As Decimal
Dim sZoneChar As String
Dim convertedNumber As Decimal
Dim sPositive As String = "{ABCDEFGHI"
Dim sNegativeMod As String = "}JKLMNOPQR"
Dim sNegativeStrict As String = "pqrstuvwxy"
strNumber = strNumber.Trim
If strNumber = "" Then
Return 0
End If
sZoneChar = strNumber.Substring(strNumber.Length - 1)
Select Case True
Case sPositive.IndexOf(sZoneChar) > -1
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sPositive.IndexOf(sZoneChar)
convertedNumber = Convert.ToDecimal(strNumber)
Case sNegativeMod.IndexOf(sZoneChar) > -1
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeMod.IndexOf(sZoneChar)
convertedNumber = -Convert.ToDecimal(strNumber)
Case sNegativeStrict.IndexOf(sZoneChar) > -1
strNumber = strNumber.Substring(0, strNumber.Length - 1) & sNegativeStrict.IndexOf(sZoneChar)
convertedNumber = -Convert.ToDecimal(strNumber)
Case Else
convertedNumber = Convert.ToDecimal(strNumber)
End Select
Return Convert.ToDecimal(convertedNumber / (10 ^ decimalPlaces))
End Function
当前文件
0x0200EAA4 转换为 EBCDIC 是 x0200529F,这是一个有效的 comp-3 值 (2020-May-29)。
运行 对二进制 EBCDIC 文件(如此文件)的 ascii 转换会损坏 文件 不要尝试处理当前文件。
解决方案
在源计算机(大型机??)上将文件转换为文本,transmit/translate 文件
如果处理 Mainframe Cobol 文件,请查看 cb2xml。它将 Cobol Copybook 转换为 Xml 文件(并计算位置/长度)。 Xml可以处理多种语言。
在源计算上转换为固定长度(可能已经是固定长度)并传输 作为 EBCDIC 文件。该文件中不会有任何回车 return 换行符。 您需要将其作为 EBCDIC 文件进行处理。
如果可以
- 运行 java
- 获取 Cobol Copybook
- Cobol copybook没有重新定义
像CobolToCsv这样的东西可以将文件从Cobol-Ebcdic转换成Ascii-Csv文件
EBCDIC
有多个EBCDIC字符集Cp037/IBM037是US EBCDIC; CP273/IBM273 是德语 EBCDIC,您需要找出正在使用的 EBCDIC 方言
注:CP037代表编码页037
大型机固定宽度
主机固定宽度,所有记录都是相同长度并且有 没有 Carriage Return / Line Feed 字符。 对于具有 26 字节记录的文件,它是
<-- 26 bytes --><-- 26 bytes --> ... <-- 26 bytes -->
cb2xml
cb2xml 会将 Cobol Copybook 转换为 xml。这允许在大多数现代语言中对 Cobol 数据进行通用处理
cb2xml 将转换
01 Location-Record.
03 Record-Type pic xx.
03 location occurs 10.
05 DC-Number pic 9(4).
05 Pack-Quantity pic 9(8).
到
<item display-length="122" level="01" name="Location-Record" position="1" storage-length="122">
<item display-length="2" level="03" name="Record-Type" picture="xx" position="1" storage-length="2"/>
<item display-length="12" level="03" name="location" occurs="10" position="3" storage-length="12">
<item display-length="4" level="05" name="DC-Number" numeric="true" picture="9(4)" position="3" storage-length="4"/>
<item display-length="8" level="05" name="Pack-Quantity" numeric="true" picture="9(8)" position="7" storage-length="8"/>
</item>
</item>