5

開発者からもらったもの

まず最初に、申し訳ありませんが、ばかげた質問をしようと思います。私は Java をまったく知らないし、このような質問をしてよいかどうかもわかりません。

そうでない場合は、トピックを削除してください。

オラクルには、ブロブを格納するテーブルがあります。それはバイナリで、デコードできます。出力は次のようになります

¬í sr /com.epam.insure.credentialing.forms.StorageBeanÀÓ ¯w/§ L     variablest Ljava/util/Map;xpsr java.util.HashMapÚÁÃ`Ñ F 
loadFactorI     thresholdxp?@     w      t $_hasCompletedt  t 
$_wf_progresssr java.lang.Integerâ ¤÷‡8 I valuexr java.lang.Number†¬•”à‹  xp   t $_wf_statussq ~    t $_form_instance_idsr java.lang.Long;‹äÌ#ß J valuexq ~          ‹©t $_isVisitedt truet 1sq ~  sq ~ ?@     `w   €   _t  confidential readable infot 1t confidential readable infot $_errorssr java.util.ArrayListxÒ™Ça I sizexp    w   
xt regionIdsq ~       ët 
confidential readable infot t  t $_subbean_errorssq ~     w   
xt regiont  SOUTHWESTt idt  t codet  t reqTypeNamet 
confidential readable infot t confidential readable infot tint  t $_hasCompletedt falset comRequiredt  t 
lineImpactq ~ t prChiropractorsq ~ t fromTypeReqt not zipt 342t changeToTypeReq6t confidential readable infot t 
prPodiatristsq ~ t 
$_isValidatedt truet $_hasErrorsq ~ -t EVPapprovalsq ~  sq ~ ?@     w   Approvedq ~ Ct 
NEGOTIATORq ~ Et 
Negotiatort datet 
03/31/2006q ~ It confidential readable infot q ~ \xt updateRequiredt noq ~ t truet  approverssr .forms.StorageBeanList«WtúœG  xq ~    w   
q ~ Rsq ~  sq ~ ?@     w      t commentst  t decisiont Approvedq ~ Ct RVPq ~ Et RVPt datet 
04/04/2006q ~ It t commentst  t decisiont Approvedq ~ Ct COOq ~ Et COOt datet 
04/14/2006q ~ It ~ †xsq ~  sq ~ ?@     w      t commentsq ~ Pt decisiont Approvedq ~ Ct CEOq ~ Et CEOt d

ここに私の質問があります

  1. 何らかの理由で、デコードされたブロブ値(上に投稿したもの)をテーブルに挿入しようとすると(MS Accessに移動してそこで解析するつもりでした。これは恐ろしい解決策ですが、必死です)-挿入される唯一のものは、引用符なしの「¬í」です。また、すべてを選択して DBMS 出力ウィンドウからコピーすることもできません。ここでも、貼り付けられるのは引用符のない「¬í」だけです。このテキストは実際には存在しないようです。テーブルに挿入する方法を知っている人はいますか?

  2. 正しい方法で Java を使用するとしたら、どこから始めればよいでしょうか? このばかげたことを許してください、しかし、私はJavaコードを実行する方法さえ知りません。ネットでいくつかのサンプルコードを見つけましたが、どこに貼り付けるかわかりません:)

私はそれをグーグルで調べたところ、テキストエディタで.javaファイルを作成してからコンパイルする必要があることがわかりました.私の場合はそうですか? おそらくそれはいくつかの異なるJavaコードだと思いました。私の場合は、テーブルがある場所にあるため、Oracleから実行する必要があると思いました。

私もテーブル構造を持っています、私はそれを添付しました。このブロブにはテーブルが格納されます。

とにかく、私が無知であることは今では明らかだと確信しています。誰かが私をどこかに向けることができれば、本当に感謝しています。

ありがとうございました

4

2 に答える 2

5

BLOB から Java オブジェクトを逆シリアル化する Oracle 11g Java ストアド関数の例を次に示します。無料ボーナスとして、シリアル化された Java オブジェクトで BLOB を更新する Oracle Java ストアド プロシージャの例が追加されました。

オブジェクトのクラスが Java に組み込まれていない場合 (私の場合のように)、そのソースを (すべての依存関係と共に) Oracle データベースに公開する必要もあります。

CREATE OR REPLACE JAVA SOURCE NAMED "ServiceParamsBLOBHandler" AS
import java.io.*;
import java.util.*;
public class ServiceParamsBLOBHandler {

    private static Object deserialize(InputStream stream) throws Exception {

        ObjectInputStream ois = new ObjectInputStream(stream);
        try {
            return ois.readObject();
        } finally {
            ois.close();
        }
    }

    private static byte[] serialize(Object object) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(object);
        oos.close();
        return baos.toByteArray();
    }

    //@SuppressWarnings("unchecked")
    private static List<Map<String, String>> getParams(oracle.sql.BLOB blob) throws Exception {
        return (List<Map<String, String>>) deserialize(blob.getBinaryStream());
    }

    public static oracle.sql.BLOB updatedParamField(oracle.sql.BLOB blob, String paramName, String fieldName, String value)
            throws Exception {

        List<Map<String, String>> params = getParams(blob);
        Map<String, String> param = getParam(params, paramName);
        param.put(fieldName, value);
        oracle.sql.BLOB res = oracle.sql.BLOB.createTemporary(blob.getOracleConnection(), true, oracle.sql.BLOB.DURATION_CALL);
        res.setBytes(1, serialize(params));
        return res;
    }

    public static void updateParamField(oracle.sql.BLOB[] blobs, String paramName, String fieldName, String value)
            throws Exception {

        oracle.sql.BLOB blob = blobs[0];
        List<Map<String, String>> params = getParams(blob);
        Map<String, String> param = getParam(params, paramName);
        param.put(fieldName, value);
        blob.truncate(0);
        blob.setBytes(1, serialize(params));
    }

    private static Map<String, String> getParam(List<Map<String, String>> params, String name) {
        for (Map<String, String> param : params) {
            if (name.equals(param.get("name"))) {
                return param;
            }
        }
        return null;
    }

    public static String getParamField(oracle.sql.BLOB blob, String paramName, String fieldName) throws Exception {
        Map<String, String> param = getParam(getParams(blob), paramName);
        return param == null ? null : param.get(fieldName);
    }

}
/

alter java source "ServiceParamsBLOBHandler" compile
--select * from SYS.USER_ERRORS
/

CREATE OR REPLACE function getServiceParamField(b IN BLOB, paramName IN VARCHAR2, fieldName IN VARCHAR2) RETURN VARCHAR2
as LANGUAGE JAVA NAME 'ServiceParamsBLOBHandler.getParamField(oracle.sql.BLOB, java.lang.String, java.lang.String) return String';
/

CREATE OR REPLACE function updatedServiceParamField(b IN BLOB, paramName IN VARCHAR2, fieldName IN VARCHAR2, value IN VARCHAR2) RETURN BLOB
as LANGUAGE JAVA NAME 'ServiceParamsBLOBHandler.updatedParamField(oracle.sql.BLOB, java.lang.String, java.lang.String, java.lang.String) return oracle.sql.BLOB';
/

CREATE OR REPLACE PROCEDURE updateServiceParamField(b IN OUT BLOB, paramName IN VARCHAR2, fieldName IN VARCHAR2, value IN VARCHAR2)
AS LANGUAGE JAVA NAME 'ServiceParamsBLOBHandler.updateParamField(oracle.sql.BLOB[], java.lang.String, java.lang.String, java.lang.String)';
/

-- oracle blob read usage example:
select getServiceParamField(byte_value, 'account', 'format') from entity_property where name='params';

-- oracle blob update with java stored function usage example:
update entity_property set byte_value=updatedServiceParamField(byte_value, 'account', 'format', '15')
where name='params' and entity_id = 123

-- oracle blob update with java stored procedure usage example:
BEGIN
   FOR c IN (select byte_value from entity_property where name='params' and entity_id = 123 for update) LOOP
       updateServiceParamField(c.byte_value, 'account', 'format', '13');
   END LOOP;
END;
/

アップデート

問題のケースの具体的なスニペット。

1) 全オブジェクトロード

    private static String getVariable(oracle.sql.BLOB blob, String name) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(blob.getBinaryStream());
        try {
            //noinspection unchecked
            return ((HashMap<String, String>) ((StorageBean) ois.readObject()).variables).get(name);
        } finally {
            ois.close();
        }
    }

2) 部分的な現場負荷

    private static String getVariable(oracle.sql.BLOB blob, String name) throws Exception {
        ObjectInputStream ois = new ObjectInputStream(blob.getBinaryStream());
        try {
            ois.skipBytes(variablesOffset);
            //noinspection unchecked
            return ((HashMap<String, String>) ois.readObject()).get(name);
        } finally {
            ois.close();
        }
    }
于 2013-07-24T17:22:29.167 に答える
2

ある時点でJavaでこれを行うことを学びますが、これは急いでいるので、SQLを使用してブロブからフィールドを抽出することにしました。他の誰かがこれをやろうと必死になっている場合に備えて、私はこれをここに置いています。

これは非常に醜く遅い解決策ですが、これまでのところいくつかのフィールドを取得できています。完了したら、すべてを取得できたかどうかを更新します。

これが私が使用しているコードです(これは1つのフィールドのみですが、アイデアが得られます)

    DECLARE
     CURSOR c_dts IS
       SELECT Form_ID
         FROM NR_DTS_FORMTABLE
        WHERE   1 = 1
           --AND ROWNUM BETWEEN 501 AND 4500
           AND form_ID > 204815
           --AND ROWNUM < 5000
           AND ROWNUM < 3
           --AND form_id IN (SELECT form_id FROM NR_DTS_BLOB)
           AND Form_Type_ID = 102;
     DTS c_dts%ROWTYPE;
BEGIN
     OPEN c_dts;
     LOOP
       FETCH c_dts INTO DTS;
       EXIT WHEN c_dts%NOTFOUND;
       DECLARE
         v_hold_blob BLOB;
         v_len NUMBER;
         v_raw_chunk RAW(10000);
         v_chr_string VARCHAR2(32767);
         -- v_chr_string CLOB;
         v_position NUMBER;
         c_chunk_len NUMBER := 1;
         Form_ID NUMBER;
       BEGIN
         SELECT form_content
           INTO v_hold_blob
           FROM NR_DTS_FORMTABLE
          WHERE Form_ID = DTS.Form_ID;
         v_len := DBMS_LOB.getlength(v_hold_blob);
         v_position := 1;
         WHILE (v_position <= LEAST(v_len, 32767)) LOOP
              v_raw_chunk := DBMS_LOB.SUBSTR(v_hold_blob, c_chunk_len, v_position);
              v_chr_string := v_chr_string || CHR(hex_to_decimal(RAWTOHEX(v_raw_chunk)));
              v_position := v_position + c_chunk_len;
         END LOOP;

         --insert into table
         INSERT INTO NR_DTS_BLOBFIELDS_VARCHAR(formid
                               ,regionId)
              SELECT DTS.Form_ID
                 ,SUBSTR(v_chr_string
                     ,INSTR(v_chr_string, 'regionIdt') + LENGTH('regionIdt') + 2
                     ,INSTR((SUBSTR(v_chr_string, INSTR(v_chr_string, 'regionIdt') + LENGTH('regionIdt') + 2))
                        ,CHR(116) || CHR(0)))
                    regionId
             FROM DUAL;
       END;
     --  DBMS_OUTPUT.put_line(DTS.Form_ID);
     END LOOP;
     CLOSE c_dts;
END;
于 2013-02-13T03:34:43.240 に答える