首先,我道歉,我将要问一些愚蠢的问题。我不知道java AT ALL,我不知道是否允许我们提出这样的问题。
如果没有 - 删除我的主题。
oracle中有一个存储blob的表。它是二进制的,我能够解码它,输出看起来像这样
¬í 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
所以这是我的问题
由于某种原因,当我尝试将解码的blob值(我上面发布的内容)插入表格时(我打算将其移动到MS Access并在那里解析它。这将是一个可怕的解决方案,但我很绝望) - 唯一插入的是没有引号的“¬í”。此外,我无法选择所有并从DBMS输出窗口复制它,再次,唯一粘贴的是没有引号的“¬í”。似乎这个文本并不存在。有没有人知道如何将其插入表中?
如果我以正确的方式做到并使用java,我从哪里开始?原谅这种愚蠢,但我甚至不知道如何运行java代码。我在网上找到了一些示例代码,但我不知道在哪里粘贴它:)
我确实google了,看到我必须在文本编辑器中创建一个.java文件然后编译它,这对我的情况是否正确?我想也许这是一些不同的java代码,我想也许在我的情况下我必须从oracle运行它,因为那是表的位置。
我也有桌子结构,我附上了一块。这个blob存储了一个表。
无论如何,我确信现在很明显我一无所知。如果有人能指出某个地方,我真的很感激。
谢谢
答案 0 :(得分:3)
这是一个oracle 11g java存储函数的示例,它从blob反序列化java对象。作为免费奖金添加了一个oracle java存储过程的示例,用于更新带有序列化java对象的blob。
如果object的类不是java内置的(在我的例子中),你还需要在oracle数据库中publish它的源代码(带有所有依赖项)。
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();
}
}
答案 1 :(得分:1)
我会在某些时候学会在java中这样做,但由于这是一个匆忙 - 我决定使用SQL从blob中提取字段。我把它放在这里以防万一其他人非常渴望这样做。
这是一个非常丑陋和缓慢的解决方案,但到目前为止,我能够得到一些领域。一旦我完成,我会更新,说我是否能够得到所有东西。
这是我正在使用的代码(这仅适用于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;