7

我在带有 LINQ to SQL 的存储过程中使用临时表。我将存储过程添加到 Linq to SQL dbml 文件,然后项目出现错误消息

“未知返回类型 - 无法检测到以下存储过程的返回类型。”</p>

当我在存储过程中删除临时表时,返回值很好。

如何在带有 Linq to SQL 的存储过程中使用临时表

我像这样替换诱惑

  CREATE TABLE tempTable(
PartsReceivingID INT, 
SoPartID INT,
RecvQty INT,
ReturnQty INT
)

像下面这样替换

  SELECT @RowCount = count(*)           
  FROM Parts.studentTempTable          
   IF @RowCount > 0         
           BEGIN             
             TRUNCATE TABLE Parts.studentTempTable;
           END  

工作版存储过程

ALTER  PROCEDURE [dbo].[stp_student_Select_New] 
                @pSchID as int, 
                @pCompanyID as int,
                @pAgingDate as int,
                @pTicketNo as VARCHAR(50),
                @pInvoiceNo as VARCHAR(50),
                @pDeliveryNo as VARCHAR(50),
                @pPartNo as VARCHAR(50)
As
SET NOCOUNT ON
BEGIN
          SELECT @RowCount = count(*)
          FROM Parts.studentTempTable

        IF @RowCount > 0
        BEGIN
            TRUNCATE TABLE Parts.studentTempTable;
        END


    ===============================================
    do something with studentTempTable
    ===============================================

        SELECT 
               r.Ticketid AS TicketID,
               r.SoPartNo  AS PartNo ,
               p.Description,
               r.InvoiceNo as InvoiceNo,
               r.InvoiceDate AS InvoiceDate,
               DATEDIFF(DY,r.InvoiceDate,GETDATE())as Aging,
               r.Qty AS CurrentInventory,              
               t.ReturnQty AS ReturnQty
        FROM Parts.studentTempTable AS t,
             Parts.PartsReceiving AS r,
             Parts.PartsInfo as p
        WHERE t.PartsReceivingID = r.PartsReceivingID
          --and i.TicketID = r.TicketID 
          and p.PartID = r.SoPartID  
          and t.ReturnQty >0 
          and DATEDIFF(DY,r.InvoiceDate,GETDATE()) > @pAgingDate
          and r.SchID = @pSchID 
          and r.CompanyID = @pCompanyID
          and r.SoPartNo like  '%%' + @pTicketNo + '%' 
          and r.InvoiceNo like  '%%' + @pInvoiceNo + '%' 
          and r.SoPartNo like  '%%' + @pPartNo + '%' 
          --and i.TicketNo like  '%%' + @pTicketNo + '%' 
          --and r.DeliverNo like  '%%' + @pDeliveryNo + '%' 
Return
END

无 工作版本存储过程

ALTER PROCEDURE [dbo].[stp_student_Select] 
                @pVendorID as int, 
                @pCompanyID as int,
                @pAgingDate as int,
                @pTicketNo as VARCHAR(50),
                @pInvoiceNo as VARCHAR(50),
                @pDeliveryNo as VARCHAR(50),
                @pPartNo as VARCHAR(50)

As
SET NOCOUNT ON
BEGIN
    BEGIN TRY


            CREATE TABLE tempTable(
                    PartsReceivingID INT, 
                    SoPartID INT,
                    RecvQty INT,
                    ReturnQty INT
                    )
    ===============================================
    do something with tempTable
    ===============================================
        SELECT 
               isnull(r.Ticketid,0) AS TicketID,
               --i.TicketNo,
               r.SoPartNo  AS PartNo ,
               p.Description,
               r.InvoiceNo as InvoiceNo,
               --r.DeliveryNo,
               r.InvoiceDate AS InvoiceDate,
               DATEDIFF(DY,r.InvoiceDate,GETDATE())as Aging,
               r.Qty AS CurrentInventory,              
               t.ReturnQty AS ReturnQty

        FROM tempTable AS t,
             Parts.PartsReceiving AS r,
             --Ticket.TicketInfo as i,
             Parts.PartsInfo as p

        WHERE t.PartsReceivingID = r.PartsReceivingID
          --and i.TicketID = r.TicketID 
          and p.PartID = r.SoPartID  
          and t.ReturnQty >0 
          and DATEDIFF(DY,r.InvoiceDate,GETDATE()) > @pAgingDate
          and r.VendorID = @pVendorID 
          and r.CompanyID = @pCompanyID
          and r.SoPartNo like  '%%' + @pTicketNo + '%' 
          and r.InvoiceNo like  '%%' + @pInvoiceNo + '%' 
          and r.SoPartNo like  '%%' + @pPartNo + '%' 
          --and i.TicketNo like  '%%' + @pTicketNo + '%' 
          --and r.DeliverNo like  '%%' + @pDeliveryNo + '%' 


        DROP TABLE temptable
    END TRY

    BEGIN CATCH
        SELECT ERROR_MESSAGE() as ErrorMessge,
               ERROR_NUMBER() AS ErrorNumber
    END CATCH
Return
END
4

5 回答 5

5

如果您自己运行该过程(在 SSMS 或 Visual Studio 中)它会返回结果吗?无论答案如何,我都建议您使用表变量-您当前使用的不是临时表-它只是一个表。使用表变量将排除实际创建/删除表的任何问题。谷歌搜索会找到很多信息,但这似乎信息量很大:http: //odetocode.com/code/365.aspx

于 2011-03-30T16:28:18.523 回答
0

如果 tempTable 真的是#tempTable,那么要为存储过程的结果集自动生成类,您必须在存储过程定义的开头写下这个

IF(1=2)
BEGIN
SELECT
  CAST(NULL AS BIGINT)  AS TicketID --assuming TicketId is of bigint type 
  CAST(NULL AS NVARCHAR(16) AS PartNo --assuming PartNo is of Nvarchar(16)
  .......

  END
于 2011-05-31T13:39:10.347 回答
0

虽然声明一个表变量将满足 LINQ to SQL 的要求,但由于缺少统计信息,我曾经有过一些表变量的性能非常糟糕的情况。

在那些时候,我不得不重新创建一个简单的包装器或填充存储过程来调用真正的存储过程。包装存储过程使其工作的一个要求是声明一个与实际存储过程的输出匹配的表变量并执行 INSERT...EXEC

Declare @Temp table (ColumnA int, ColumnB varchar(256))
Insert Into @Temp(ColumnA, ColumnB)
Exec dbo.OtherStoredProcedure /* pass needed parameters, if any */

Select ColumnA, ColumnB From @Temp

当然,临时表的定义必须与存储过程的输出完全匹配。你甚至不能删除列。

LINQ to SQL 此时不会评估“子”存储过程,您可以通过 LINQ to SQL 调用包装存储过程。

于 2019-05-10T22:22:48.787 回答
0

在您的 SP 的开头添加以下脚本。

IF 1=0 BEGIN
    SET FMTONLY OFF
END

FMTONLY仅将元数据返回到数据集。可用于在不实际运行查询的情况下测试响应的格式。

上面的查询将给出没有数据的列输出。

来源:https ://www.youtube.com/watch?v=zaL7fbUou7E

于 2021-02-24T11:54:32.547 回答
-1

将 sp 中使用的临时表作为表创建到原始 db 中,然后在 sp 中使用这些表,然后将 sp 放入 dbml 文件中,它将返回 sp 的返回类型。在您将 sp 在 dbml 中删除后,将原始 sp 更改为之前的样子并删除临时表形式的原始数据库

于 2012-01-06T07:27:58.077 回答