Работа с BLOB/LONG RAW в Oracle через OCI
Пытаюсь разобраться с ZEOSLIB для работы c Oracle через OCI и наткнулся на следующую проблему -
если в таблице есть поле с типом LONG RAW - то записать в него получается только 2000 байт, если поле в таблице имеет тип BLOB - то все пишется нормально.
вот синтетичиский код для записи данных, может кто ни будь указать что и как надо изменить для LONG RAW?
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .pascal.geshi_code {font-family:monospace;} .pascal.geshi_code .imp {font-weight: bold; color: red;} .pascal.geshi_code .kw1 {color: #000000; font-weight: bold;} .pascal.geshi_code .kw2 {color: #000000; font-weight: bold;} .pascal.geshi_code .kw3 {color: #000066;} .pascal.geshi_code .kw4 {color: #000066; font-weight: bold;} .pascal.geshi_code .co1 {color: #666666; font-style: italic;} .pascal.geshi_code .coMULTI {color: #666666; font-style: italic;} .pascal.geshi_code .es0 {color: #000099; font-weight: bold;} .pascal.geshi_code .es_h {color: #000099; font-weight: bold;} .pascal.geshi_code .br0 {color: #009900;} .pascal.geshi_code .sy0 {color: #339933;} .pascal.geshi_code .st0 {color: #ff0000;} .pascal.geshi_code .st_h {color: #ff0000;} .pascal.geshi_code .nu0 {color: #cc66cc;} .pascal.geshi_code .me1 {color: #0066ee;} .pascal.geshi_code span.xtra { display:block; }
var
sql: string;
Handle: POCIStmt;
ErrorHandle: POCIError;
conn: IZOracleConnection;
FPlainDriver: IZOraclePlainDriver;
BindHandle, buff: Pointer;
Status,buflen: integer;
lob: POCILobLocator;
begin
sql := 'update t2 set b = :p1 where id = 10';
ZConnection1.Connect; // подключение к Oracle
conn := ZConnection1.DbcConnection as IZOracleConnection;
FPlainDriver := conn.GetPlainDriver;
Caption := FPlainDriver.GetDescription;
with TFileStream.Create('c:ttestfile.txt', fmOpenRead or fmShareDenyNone) do
begin
buflen := Size;
GetMem(buff, buflen);
ReadBuffer(buff^, buflen);
Free;
end;
AllocateOracleStatementHandles(FPlainDriver, conn, Handle, ErrorHandle);
try
PrepareOracleStatement(FPlainDriver, sql, Handle, ErrorHandle);
Status := FPlainDriver.DescriptorAlloc(conn.GetConnectionHandle, lob,
OCI_DTYPE_LOB, 0, nil);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Open Large Object');
Status := FPlainDriver.LobCreateTemporary(conn.GetContextHandle,
conn.GetErrorHandle, lob, OCI_DEFAULT, OCI_DEFAULT,
OCI_TEMP_BLOB, False, OCI_DURATION_DEFAULT);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Create Large Object');
Status := FPlainDriver.LobOpen(conn.GetContextHandle,
conn.GetErrorHandle, lob, OCI_LOB_READWRITE);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Open Large Object');
Status := FPlainDriver.LobWrite(conn.GetContextHandle,
conn.GetErrorHandle, lob, buflen, 1,
buff, buflen, OCI_ONE_PIECE, nil, nil, 0, SQLCS_IMPLICIT);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Write Large Object');
FreeMem(buff);
Status := FPlainDriver.LobClose(conn.GetContextHandle,
conn.GetErrorHandle, lob);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Close Large Object');
Status := FPlainDriver.BindByPos(Handle, BindHandle,
ErrorHandle, 1, @lob, SizeOf(POCILobLocator),
SQLT_BLOB, nil, nil, nil, 0, nil,
OCI_DEFAULT);
CheckOracleError(FPlainDriver, ErrorHandle, Status, lcExecute, sql);
ExecuteOracleStatement(FPlainDriver, conn, sql, Handle, ErrorHandle);
Status := GetOracleUpdateCount(FPlainDriver, Handle, ErrorHandle);
FPlainDriver.DescriptorFree(lob, OCI_DTYPE_LOB);
finally
FreeOracleStatementHandles(FPlainDriver, Handle, ErrorHandle);
end;
conn.Commit;
end;
если в таблице есть поле с типом LONG RAW - то записать в него получается только 2000 байт, если поле в таблице имеет тип BLOB - то все пишется нормально.
вот синтетичиский код для записи данных, может кто ни будь указать что и как надо изменить для LONG RAW?
/** * GeSHi (C) 2004 - 2007 Nigel McNie, 2007 - 2008 Benny Baumann * (http://qbnz.com/highlighter/ and http://geshi.org/) */ .pascal.geshi_code {font-family:monospace;} .pascal.geshi_code .imp {font-weight: bold; color: red;} .pascal.geshi_code .kw1 {color: #000000; font-weight: bold;} .pascal.geshi_code .kw2 {color: #000000; font-weight: bold;} .pascal.geshi_code .kw3 {color: #000066;} .pascal.geshi_code .kw4 {color: #000066; font-weight: bold;} .pascal.geshi_code .co1 {color: #666666; font-style: italic;} .pascal.geshi_code .coMULTI {color: #666666; font-style: italic;} .pascal.geshi_code .es0 {color: #000099; font-weight: bold;} .pascal.geshi_code .es_h {color: #000099; font-weight: bold;} .pascal.geshi_code .br0 {color: #009900;} .pascal.geshi_code .sy0 {color: #339933;} .pascal.geshi_code .st0 {color: #ff0000;} .pascal.geshi_code .st_h {color: #ff0000;} .pascal.geshi_code .nu0 {color: #cc66cc;} .pascal.geshi_code .me1 {color: #0066ee;} .pascal.geshi_code span.xtra { display:block; }
var
sql: string;
Handle: POCIStmt;
ErrorHandle: POCIError;
conn: IZOracleConnection;
FPlainDriver: IZOraclePlainDriver;
BindHandle, buff: Pointer;
Status,buflen: integer;
lob: POCILobLocator;
begin
sql := 'update t2 set b = :p1 where id = 10';
ZConnection1.Connect; // подключение к Oracle
conn := ZConnection1.DbcConnection as IZOracleConnection;
FPlainDriver := conn.GetPlainDriver;
Caption := FPlainDriver.GetDescription;
with TFileStream.Create('c:ttestfile.txt', fmOpenRead or fmShareDenyNone) do
begin
buflen := Size;
GetMem(buff, buflen);
ReadBuffer(buff^, buflen);
Free;
end;
AllocateOracleStatementHandles(FPlainDriver, conn, Handle, ErrorHandle);
try
PrepareOracleStatement(FPlainDriver, sql, Handle, ErrorHandle);
Status := FPlainDriver.DescriptorAlloc(conn.GetConnectionHandle, lob,
OCI_DTYPE_LOB, 0, nil);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Open Large Object');
Status := FPlainDriver.LobCreateTemporary(conn.GetContextHandle,
conn.GetErrorHandle, lob, OCI_DEFAULT, OCI_DEFAULT,
OCI_TEMP_BLOB, False, OCI_DURATION_DEFAULT);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Create Large Object');
Status := FPlainDriver.LobOpen(conn.GetContextHandle,
conn.GetErrorHandle, lob, OCI_LOB_READWRITE);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Open Large Object');
Status := FPlainDriver.LobWrite(conn.GetContextHandle,
conn.GetErrorHandle, lob, buflen, 1,
buff, buflen, OCI_ONE_PIECE, nil, nil, 0, SQLCS_IMPLICIT);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Write Large Object');
FreeMem(buff);
Status := FPlainDriver.LobClose(conn.GetContextHandle,
conn.GetErrorHandle, lob);
CheckOracleError(FPlainDriver, conn.GetErrorHandle,
Status, lcOther, 'Close Large Object');
Status := FPlainDriver.BindByPos(Handle, BindHandle,
ErrorHandle, 1, @lob, SizeOf(POCILobLocator),
SQLT_BLOB, nil, nil, nil, 0, nil,
OCI_DEFAULT);
CheckOracleError(FPlainDriver, ErrorHandle, Status, lcExecute, sql);
ExecuteOracleStatement(FPlainDriver, conn, sql, Handle, ErrorHandle);
Status := GetOracleUpdateCount(FPlainDriver, Handle, ErrorHandle);
FPlainDriver.DescriptorFree(lob, OCI_DTYPE_LOB);
finally
FreeOracleStatementHandles(FPlainDriver, Handle, ErrorHandle);
end;
conn.Commit;
end;