1

Binary(7) として定義されている列を含む SQL Server テーブルがあります。これは、Comp-3 データ (パック 10 進数) を持つ COBOL プログラムからのデータで更新されます。数値を取得して Comp-3 値を作成する C# プログラムを作成しました。CLR統合を介してSQL Serverで利用できます。ストアドプロシージャのようにアクセスできます。

私の問題は、このプログラムから値を取得してバイナリ列に保存する必要があることです。既にそこにあるデータの行を選択すると、次のような値が表示されます。

0x00012F0000000F

表示されている値は、SQL テーブルに格納されている COBOL comp-3 (パック 10 進数) データです。このフィールドは Binary(7) として定義されていることに注意してください。2 つの値が連結され、ここに格納されます。符号なし値 12、および符号なし値 0。

0x00012F (長さ 3 文字) と 0x0000000F (長さ 4 文字) を連結して列に書き込む必要があります。

私の質問は 2 つの部分です。

1) プログラムから Comp-3 値の文字列表現を返すことができます。しかし、これがこの作業を行うために返す必要がある形式であるかどうかはわかりません。SQL を正しく使用するには、どの形式で SQL に返す必要がありますか?

2) これを変換して機能させるにはどうすればよいですか?

私が十分に明確だったことを願っています。消化するのは大変です...ありがとう!

4

2 に答える 2

1

私はそれを考え出した!出力を byte[] に変更し、SQL でプログラムから出力される出力を varbinary として参照する必要がありました。

これは、将来誰かがそれを必要とする場合のコードです。これが、SQL で Comp-3 (パック 10 進数) を作成する必要がある他の人に役立つことを願っています。以下にそれを使用する手順の概要を説明します。

以下は、C# プログラムのソースです。dllとしてコンパイルします。

using System;
using System.Collections.Generic;
using System.Data;
using Microsoft.SqlServer.Server;
using System.Data.SqlTypes;

namespace Numeric2Comp3
{
//PackedDecimal conversions

public class PackedDecimal
{

    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void ToComp3(string numberin, out byte[] hexarray, out string hexvalue)
    {

        long value;
        bool result = Int64.TryParse(numberin, out value);

        if (!result)
        {
            hexarray = null;
            hexvalue = null;
            return;
        }

        Stack<byte> comp3 = new Stack<byte>(10);

        byte currentByte;
        if (value < 0)
        {
            currentByte = 0x0d;     //signed -
            value = -value;
        }
        else if (numberin.Trim().StartsWith("+"))
        {
            currentByte = 0x0c;     //signed +
        }
        else
        {
            currentByte = 0x0f;     //unsigned 
        }

        bool byteComplete = false;
        while (value != 0)
        {
            if (byteComplete)
                currentByte = (byte)(value % 10);
            else
                currentByte |= (byte)((value % 10) << 4);
            value /= 10;
            byteComplete = !byteComplete;
            if (byteComplete)
                comp3.Push(currentByte);
        }
        if (!byteComplete)
            comp3.Push(currentByte);
        hexarray = comp3.ToArray();
        hexvalue = bytesToHex(comp3.ToArray());
    }

    private static string bytesToHex(byte[] buf)
    {
        string HexChars = "0123456789ABCDEF";
        System.Text.StringBuilder sb = new System.Text.StringBuilder((buf.Length / 2) * 5 + 3);
        for (int i = 0; i < buf.Length; i++)
        {
            sbyte b = Convert.ToSByte(buf[i]);
            b = (sbyte)(b >> 4);     // Hit to bottom
            b = (sbyte)(b & 0x0F);   // get HI byte
            sb.Append(HexChars[b]);
            b = Convert.ToSByte(buf[i]);             // refresh
            b = (sbyte)(b & 0x0F);   // get LOW byte
            sb.Append(HexChars[b]);
        }
        return sb.ToString();
    } 

} 
}

dll を SQL Server マシンのフォルダーに保存します。「C:\NTA\Libraries\Numeric2Comp3.dll」を使用しました。

次に、SQL Server で CLR 統合を有効にする必要があります。これについては、Microsoft の Web サイト ( SQL Server CLR 統合の概要) を参照してください。SQL Server Management Studio を開き、次を実行して CLR 統合を有効にします。

sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'clr enabled', 1;
GO
RECONFIGURE;
GO

それが完了したら、Management Studio で次を実行します。

CREATE ASSEMBLY Numeric2Comp3 from 'C:\NTA\Libraries\Numeric2Comp3.dll' WITH PERMISSION_SET = SAFE

何らかの理由で必要な場合は、次のコマンドを実行してアセンブリを削除できます。

drop assembly Numeric2Comp3

次に、Management studio で次のコマンドを実行して、dll を参照するストアド プロシージャを作成します。

CREATE PROCEDURE Numeric2Comp3
@numberin nchar(27), @hexarray varbinary(27) OUTPUT, @hexstring nchar(27) OUTPUT
AS
EXTERNAL NAME Numeric2Comp3.[Numeric2Comp3.PackedDecimal].ToComp3

上記のすべてが正常に実行されれば、完了です!

これをテストするための SQL を次に示します。

DECLARE @in nchar(27), @hexstring nchar(27), @hexarray varbinary(27)
set @in = '20120123'
EXEC Numeric2Comp3 @in, @hexarray out, @hexstring out

select len(@hexarray), @hexarray

select len(@hexstring), @hexstring

これにより、次の値が返されます。

(No column name)    (No column name)
5                   0x020120123F

(No column name)    (No column name)
10                  020120123F                 

私の場合、必要なのは @hexarray からの値です。これは、テーブルの Binary 列に書き込まれます。

これがそれを必要とする他の人に役立つことを願っています!

于 2014-07-11T12:16:27.763 に答える