如何通过 LINQ to SQL 在存储过程中使用临时表
我在 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果您单独运行该过程(在 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
如果 tempTable 确实是 #tempTable 那么要自动生成存储过程的结果集的类,您必须在存储过程定义的开头编写它
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
虽然声明表变量可以满足 LINQ to SQL 的要求,但我也曾遇到过由于缺乏统计信息而导致表变量执行得很糟糕的情况。
在那些时候,我不得不恢复到创建一个简单的包装器或垫片存储过程的技巧,它只调用真正的存储过程。包装存储过程要使其工作,需要声明一个与实际存储过程的输出相匹配的表变量,并执行 INSERT...EXEC
当然,临时表的定义必须与实际存储过程的输出完全匹配。存储过程。您甚至不能删除列。
此时 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
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.
在 SP 的开头添加以下脚本。
FMTONLY
仅返回数据集的元数据。可用于测试响应的格式,而无需实际运行查询。上面的查询将给出没有数据的列输出。
来源:https://www.youtube.com/watch?v=zaL7fbUou7E
Add below script in beginning of your SP.
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
将 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