Пример #1
0
    public override void Execute(int timeout, IDescriptorFiller descriptorFiller)
    {
        EnsureNotDeallocated();

        descriptorFiller.Fill(_parameters, 0);

        ClearStatusVector();
        NativeHelpers.CallIfExists(() =>
        {
            _db.FbClient.fb_dsql_set_timeout(_statusVector, ref _handle, (uint)timeout);
            _db.ProcessStatusVector(_statusVector);
        });

        ClearStatusVector();

        var inSqlda  = IntPtr.Zero;
        var outSqlda = IntPtr.Zero;

        if (_parameters != null)
        {
            inSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _parameters);
        }
        if (StatementType == DbStatementType.StoredProcedure)
        {
            Fields.ResetValues();
            outSqlda = XsqldaMarshaler.MarshalManagedToNative(_db.Charset, _fields);
        }

        var trHandle = _transaction.HandlePtr;

        _db.FbClient.isc_dsql_execute2(
            _statusVector,
            ref trHandle,
            ref _handle,
            IscCodes.SQLDA_VERSION1,
            inSqlda,
            outSqlda);

        if (outSqlda != IntPtr.Zero)
        {
            var descriptor = XsqldaMarshaler.MarshalNativeToManaged(_db.Charset, outSqlda, true);

            var values = new DbValue[descriptor.Count];

            for (var i = 0; i < values.Length; i++)
            {
                var d     = descriptor[i];
                var value = d.DbValue.GetValue();
                values[i] = new DbValue(this, d, value);
            }

            OutputParameters.Enqueue(values);
        }

        XsqldaMarshaler.CleanUpNativeData(ref inSqlda);
        XsqldaMarshaler.CleanUpNativeData(ref outSqlda);

        _db.ProcessStatusVector(_statusVector);

        if (DoRecordsAffected)
        {
            RecordsAffected = GetRecordsAffected();
        }
        else
        {
            RecordsAffected = -1;
        }

        State = StatementState.Executed;
    }
    public override ExecuteResultItem[] Execute(int count, IDescriptorFiller descriptorFiller)
    {
        var parametersData = new byte[count][];

        for (var i = 0; i < parametersData.Length; i++)
        {
            descriptorFiller.Fill(_statement.Parameters, i);
            // this may throw error, so it needs to be before any writing
            parametersData[i] = _statement.WriteParameters();
        }

        Database.Xdr.Write(IscCodes.op_batch_create);
        Database.Xdr.Write(_statement.Handle);         // p_batch_statement
        var blr = _statement.Parameters.ToBlr();

        Database.Xdr.WriteBuffer(blr.Data);     // p_batch_blr
        Database.Xdr.Write(blr.Length);         // p_batch_msglen
        var pb = new BatchParameterBuffer();

        if (_statement.ReturnRecordsAffected)
        {
            pb.Append(IscCodes.Batch.TAG_RECORD_COUNTS, 1);
        }
        if (MultiError)
        {
            pb.Append(IscCodes.Batch.TAG_MULTIERROR, 1);
        }
        Database.Xdr.WriteBuffer(pb.ToArray());         // p_batch_pb

        Database.Xdr.Write(IscCodes.op_batch_msg);
        Database.Xdr.Write(_statement.Handle);         // p_batch_statement
        Database.Xdr.Write(parametersData.Length);     // p_batch_messages
        foreach (var item in parametersData)
        {
            Database.Xdr.WriteOpaque(item, item.Length);             // p_batch_data
        }

        Database.Xdr.Write(IscCodes.op_batch_exec);
        Database.Xdr.Write(_statement.Handle);             // p_batch_statement
        Database.Xdr.Write(_statement.Transaction.Handle); // p_batch_transaction;

        Database.Xdr.Flush();

        var numberOfResponses = 3;

        try
        {
            numberOfResponses--;
            var batchCreateResponse = Database.ReadResponse();
            numberOfResponses--;
            var batchMsgResponse = Database.ReadResponse();
            numberOfResponses--;
            var batchExecResponse = (BatchCompletionStateResponse)Database.ReadResponse();

            return(BuildResult(batchExecResponse));
        }
        finally
        {
            Database.SafeFinishFetching(numberOfResponses);
        }
    }