Как записать данные LONG RAW, используя OCI и Lob locator? - PullRequest
1 голос
/ 22 марта 2011

Я хочу исправить zeoslib Ошибка при написании длинного описания ошибки необработанных данных:

Memo1.Lines.LoadFromFile('c:\t\ZDbcMetadata.pas'); // file size ~ 170Kb
ZQuery1.SQL.Text := 'insert into t1(id, b) values(10, :p1)';
ZQuery1.Params[0].AsBlob := Memo1.Lines.Text;
ZQuery1.ExecSQL;

Проблема в том, что только первые 2000 байтов загружены в таблицу

в OCIкод zeos делает так:

  var
    sql: string;
    Handle: POCIStmt;
    ErrorHandle: POCIError;
    conn: IZOracleConnection;
    FPlainDriver: IZOraclePlainDriver;
    BindHandle, buff: Pointer;
    Status,buflen: integer;
    lob: POCILobLocator;
  begin
    sql := 'insert into t1(id, b) values(10, :p1)';
    conn := ZConnection1.DbcConnection as IZOracleConnection;
    FPlainDriver := conn.GetPlainDriver;

    with TFileStream.Create('c:\t\ZDbcMetadata.pas', 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, True, OCI_DURATION_SESSION);
      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');

      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);

      FreeMem(buff);
      FPlainDriver.DescriptorFree(lob, OCI_DTYPE_LOB);
    finally
      FreeOracleStatementHandles(FPlainDriver, Handle, ErrorHandle);
    end;
    conn.Commit;

возможно ли написать длинные необработанные данные с помощью локатора локатора?как?

PS.если таблица имеет поле BLOB вместо LONG RAW, этот код работает нормально.

Ответы [ 2 ]

0 голосов
/ 10 июля 2011

Вместо этого следует использовать тип данных SQLT_LVB.

Таким образом:

    ftBlob: begin
      oLength := Length(VData);
      if oLength<2000 then begin
        VDBTYPE := SQLT_BIN;
        oData := pointer(VData);
      end else begin
        VDBTYPE := SQLT_LVB;
        oData := Pointer(PtrInt(VData)-sizeof(Integer));
        Inc(oLength,sizeof(Integer));
      end;
    end;
0 голосов
/ 24 марта 2011

LONG RAW устарела с момента выпуска Oracle 8, IIRC. Нет никакого преимущества в использовании столбца LONG RAW, и вы можете легко конвертировать их, используя функцию TO_LOB (если можете, конечно). При загрузке необработанного столбца через необработанную переменную или что-то подобное было ровно ограничение в 2000 байт, и я не знаю, были ли локаторы больших объектов когда-либо разработаны для работы с типами RAW, я думаю, они могли бы выполнять неявный перевод, типы AFAIK RAW были использованы без LOB-интерфейса - и я не стал бы связываться.

...