Skip to main content

No data is inserted/modified in temporary table when processing an SRS report using Pre-process

· 2 min read
Kome Hoang
Maintainer of Automaly

References

How to

Pre-process RDP has become very commonplace these days, especially to ones who work with SSRS reports on Dynamics 365 FO a lot.

Recently, I faced an issue when no data was inserted into or modififed in my temporary table during run-time despite the fact that RDP class (and its related ones within the same framework) was executed successfully. Even debugging did not show me what was going wrong. There was simply no SQL statements in the trace that I captured.

Turned out that I will need to take ownership of the temp table instance before manipulating any data in it.

My code used to be (when it did not work):

internal final class CSG_PostedServiveOrderWithoutInvDP extends SrsReportDataProviderPreProcessTempDB
{
CSG_PostedServiveOrderWithoutInvTmp tmpTable;

[SRSReportDataSetAttribute(tableStr(CSG_PostedServiveOrderWithoutInvTmp))]
public CSG_PostedServiveOrderWithoutInvTmp getTmpTable()
{
select tmpTable;
return tmpTable;
}

public void processReport()
{
ttsbegin;
this.populateTmpTable();
ttscommit;
}

private void populateTmpTable()
{
// Insert data to tmp table here.
}
}

I would need to call out to SrsReportDataProviderPreProcessTempDB.takeOwnershipOfTempTable() to have it work.

My code then became:

internal final class CSG_PostedServiveOrderWithoutInvDP extends SrsReportDataProviderPreProcessTempDB
{
CSG_PostedServiveOrderWithoutInvTmp tmpTable;

[SRSReportDataSetAttribute(tableStr(CSG_PostedServiveOrderWithoutInvTmp))]
public CSG_PostedServiveOrderWithoutInvTmp getTmpTable()
{
select tmpTable;
return tmpTable;
}

public void processReport()
{
ttsbegin;
// Take ownership of each and all tmpTable before using them in the RDP
this.takeOwnershipTmp();

// Data manipulation then can be conducted without an issue
this.populateTmpTable();
ttscommit;
}

private void takeOwnershipTmp()
{
// Take ownership of the current instance of tmpTable here
this.takeOwnershipOfTempTable(tmpTable);
}

private void populateTmpTable()
{
// Insert data to tmp table here.
}
}

The code behind the SrsReportDataProviderPreProcessTempDB.takeOwnershipOfTempTable() is as below (for ones who might want to implement their own framework):

/// <summary>
/// Takes ownership of the given temp table.
/// </summary>
/// <param name="_tempDbTable">
/// The table to take ownership of.
/// </param>
public void takeOwnershipOfTempTable(Common _tempDbTable)
{
DictTable dictTable;
TableId tableId;
#SRSFramework

if (!this.parmUseDefaultTransactionOnly())
{
_tempDbTable.setConnection(this.parmUserConnection());
}

tableId = _tempDbTable.TableId;
dictTable = new DictTable(tableId);
if(!dictTable)
{
throw error(strFmt("@SYS4007193", tableId2name(tableId)));
}

new ExecutePermission().assert();
dictTable.callObject(#TempDBMethodName_TakeOwnership, _tempDbTable, true);
CodeAccessPermission::revertAssert();
}