EF can't infer return schema from Stored Procedure selecting from a #temp table

后端 未结 4 1832
迷失自我
迷失自我 2020-11-27 03:02

Suppose the following:

CREATE PROCEDURE [MySPROC]
AS 
BEGIN

CREATE TABLE #tempSubset(
    [MyPrimaryKey] [bigint]  NOT NULL,
    [OtherColumn]  [int]     NO         


        
相关标签:
4条回答
  • 2020-11-27 03:20

    Adding this to the top of the stored procedure definition:

    SET FMTONLY OFF
    allowed the model to infer the schema from the temporary table without issue. As a bonus, it doesn't require additional maintenance for a contract.

    Example:

    SET FMTONLY OFF
    
    CREATE TABLE #tempTable (
        ...
    )
    
    ...
    
    SELECT * FROM #tempTable 
    
    0 讨论(0)
  • 2020-11-27 03:33
    CREATE PROCEDURE [MySPROC]
    AS 
    BEGIN
    
    --supplying a data contract
    IF 1 = 2 BEGIN
        SELECT
            cast(null as bigint)  as MyPrimaryKey,
            cast(null as int)    as OtherColumn
        WHERE
            1 = 2  
    END
    
    CREATE TABLE #tempSubset(
        [MyPrimaryKey] [bigint]  NOT NULL,
        [OtherColumn]  [int]     NOT NULL)
    
    INSERT INTO #tempSubset (MyPrimaryKey, OtherColumn) 
        SELECT SomePrimaryKey, SomeColumn 
        FROM   SomeHugeTable
        WHERE  LimitingCondition = true
    
    SELECT MyPrimaryKey, OtherColumn 
    FROM   #tempSubset
    WHERE  SomeExpensiveCondition = true
    
    END
    

    Supplying a faux data contract for the result set is the easiest, cleanest and fastest way to take care of the issue. This same problem exists in data source controls in SSIS too. .NET will read the result set from the unreachable "contract" section of the query and supply the metadata for the complex type. No performance impact and no need to comment out the SQL that does the actual work.

    0 讨论(0)
  • 2020-11-27 03:35

    Solution 1 Use a table variable instead of a temporary table.

    Solution 2 Use the Set FMTONLY off; SQL command in the procedure and you will get the column information to create a new complex type.

    Solution 3 This is not a good way, but it's a very easy way. Just add a select statement with dummy data and it will not execute because 1=0.

    you can check details on this link

    0 讨论(0)
  • 2020-11-27 03:37

    This is incomplete but when set fmtonly off does not work, you can generate the data contract using the following:

            SELECT * 
            FROM tempdb.sys.columns 
            WHERE [object_id] = OBJECT_ID(N'tempdb..#u');
    
            select case  system_type_id 
            when 62 then 'cast(null as float) as ' 
            when 175 then 'cast(null as char(' + cast(max_length as varchar(50)) + ')) as ' 
            when 167 then 'cast(null as varchar(' + cast(max_length as varchar(50)) + ')) as ' 
            when 56 then 'cast(null as int) as ' 
            when 104 then 'cast(null as bit) as ' 
            when 106 then 'cast(null as decimal(' + cast(precision as varchar(50)) + ',' + cast(scale as varchar(50)) + ')) as ' 
            when 40 then 'cast(null as date) as '            
            end
            + name + ','
            from  tempdb.sys.columns 
            WHERE [object_id] = OBJECT_ID(N'tempdb..#u');
    
    0 讨论(0)
提交回复
热议问题