Configuring Stored Procedure with Temporary Tables

Environment

Product Progress® Telerik® Reporting

Description

The SqlDataSource uses the standard ADO.NET data provider to load the report data and metadata. As of SQL Server 2016 Temporary Tables can be replaced with the better performing Memory-Optimized Tables. This includes mechanism allowing you to get the schema of temporary objects correctly. The FMTONLY setting is deprecated. For more details, please check Using Memory-Optimized Tables to Replace SQL Server Temp Tables and Table Variables.

Solution

For Cursor Variables: To be able to use stored procedures which contain cursors, you have to turn off FMTONLY in a seemingly never executed statement. In this way the data schema can be read by the Data Explorer as each state of IF-ELSE statements is evaluated when the SQL query is run by the SqlDataSource Wizard. The check will be skipped when the same SQL query is used by calling application at run-time.

BEGIN
        SET NOCOUNT ON;
         IF 1=0 BEGIN
           SET FMTONLY OFF
     END
    DECLARE @SQL NVARCHAR(MAX)
    DECLARE @Next NVARCHAR(MAX)
    DECLARE db_cursor CURSOR FOR SELECT  DISTINCT Gender From HumanResources.Employee
        . . .

END
GO

For MSSQL engines before SQL Server 2016. In order to use stored procedures containing temporary tables, you also have to turn off FMTONLY in a seemingly never executed statement. Thus the data schema of temporary tables can be read by the SqlDataSource Wizard as each state of IF-ELSE statements is evaluated when the SQL query is run by the SqlDataSource Wizard. The check will be skipped when the same SQL query is used by calling application at run-time.

For example consider the following SQL CREATE stored procedure statement:

USE AdventureWorks
GO
CREATE PROCEDURE dbo.Demo

AS
BEGIN
    SET NOCOUNT ON;
     IF 1=0 BEGIN
       SET FMTONLY OFF
     END

    CREATE TABLE #Temp
    (
        ProductID   integer NOT NULL,
        Name        nvarchar(50) COLLATE DATABASE_DEFAULT NOT NULL
    );

    INSERT INTO #Temp
        ([ProductID], [Name])
    SELECT
        p.[ProductID], p.[Name]
    FROM Production.Product AS p

    SELECT
        t.[Name], t.[ProductID]
    FROM #Temp AS t

    DROP TABLE #Temp;
END;

For MSSQL Engines after SQL Server 2014 You can use memory optimized tables, where the data schema can be obtained correctly when you work with SQL Server 2016. USE AdventureWorks

USE AdventureWorks
GO
CREATE TYPE MemoryOptTabVar as TABLE (
   [ProductID] integer NOT NULL ,
   [Name] nvarchar(50) NULL,
   INDEX IX_MemoryOptTabVar_ID NONCLUSTERED ([ProductID])
) WITH (MEMORY_OPTIMIZED = ON)
GO

CREATE PROCEDURE dbo.MemoryOptTableVarExample
AS
BEGIN
SET NOCOUNT ON;
    DECLARE @MemOptVarTab MemoryOptTabVar ;
       INSERT @MemOptVarTab ([ProductID], [Name])
    SELECT
        p.[ProductID], p.[Name]
    FROM Production.Product AS p
       SELECT * FROM @MemOptVarTab
END
GO
In this article
Not finding the help you need? Improve this article