如何通过 LINQ to SQL 在存储过程中使用临时表

发布于 2024-10-27 19:00:41 字数 4518 浏览 1 评论 0原文

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

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

当我删除存储过程中的临时表时,返回值就可以了

How can I use a temp table in a store procedure with 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

I use a temp table in a Stored Procedure with LINQ to SQL. I add the stored procedure to Linq to SQL dbml file then project occur error message

"Unknown Return Type - The return types for the following stored procedures could not be detected.”

When I delete a temp table in a stored procedure then return value is fine.

How can I use a temp table in a stored procedure with Linq to SQL

I replace the temptable like this

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

Replace like below

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

Working version stored procedure

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

None Working version stored procedure

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

情深缘浅 2024-11-03 19:00:41

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

If you run the procedure by itself (in SSMS, or Visual Studio) does it return results? Regardless of the answer, I would suggest you use a table variable - what you are currently using is not a temp table - it is just a table. Using a table variable will rule out any issues with actually creating/dropping the table. Googling will find you plenty of information, but this seems to be pretty informative: http://odetocode.com/code/365.aspx

静若繁花 2024-11-03 19:00:41

如果 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

If tempTable would really have been #tempTable then to auto generate the class for the result set of the stored proc you have to write this at the beginning of the stored proc definition

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
以往的大感动 2024-11-03 19:00:41

虽然声明表变量可以满足 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 调用包装器存储过程。

While declaring a table variable will satisfy LINQ to SQL, I have had times where a table variable, due to the lack of statistics, performed horribly.

On those times, I have had to revert to a hack of creating a simple wrapper or shim stored procedure that simply calls the real stored procedure. One requirement of the wrapper stored procedure to make it work is to declare a table variable that matches the output of the real stored procedure and perform an 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

Of course, the definition of the temp table must match exactly the output of the stored procedure. You can't even drop out columns.

LINQ to SQL will not evaluate the "sub" stored procedure at that point and you can call the wrapper stored procedure via LINQ to SQL.

随波逐流 2024-11-03 19:00:41

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

IF 1=0 BEGIN
    SET FMTONLY OFF
END

FMTONLY 仅返回数据集的元数据。可用于测试响应的格式,而无需实际运行查询。

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

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

Add below script in beginning of your SP.

IF 1=0 BEGIN
    SET FMTONLY OFF
END

FMTONLY returns only metadata to the dataset. Can be used to test the format of the response without actually running the query.

Above query will give column output without data.

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

怪我闹别瞎闹 2024-11-03 19:00:41

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

create the temp tables used in sp into orignal db as tables and then use these tables in sp after that drop sp in dbml file, it will return the return type of the sp. after you drop the sp in dbml change the original sp to as it was before and delte the temp table form orignal db

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文