使用传入的字符串列表结合 SQL Server 存储过程 WITH LOCK 和 INNER JOIN
Posted
技术标签:
【中文标题】使用传入的字符串列表结合 SQL Server 存储过程 WITH LOCK 和 INNER JOIN【英文标题】:Combining SQL Server stored procedure WITH LOCK and INNER JOIN using passed in list of strings 【发布时间】:2021-05-01 20:32:56 【问题描述】:我正在尝试创建一个 SQL 过程,我可以传递字符串列表并仅在存在现有结果并将其与 lock 语句组合时才返回某些内容。我正在使用用户定义的表类型来传递字符串列表,但我没有过多地使用程序,并且我收到了我将在下面发布的错误。我在数据库优先代码应用程序上使用 EF 6 和 C#。这是我正在尝试执行的代码以及我想如何在 C# 代码中调用它:
CREATE TYPE TaskTable
AS TABLE ( Name VARCHAR(7) );
GO
CREATE PROCEDURE [dbo].[DequeuePending]
@tasklist TaskTable READONLY
AS
SET NOCOUNT ON;
DECLARE @now AS DATETIME;
SET @now = getutcdate();
WITH cte AS
(
SELECT TOP (1) Task
FROM InProgresses
INNER JOIN @tasklist ON InProgresses.Task = @tasklist.Name WITH (ROWLOCK, READPAST)
WHERE Date < @now && InProgresses.Task IS NOT NULL
ORDER BY Date
)
DELETE cte
OUTPUT deleted.Task;
GO
我收到此错误:
必须声明标量变量@tasklist
C#代码:
var taskList = new List<string>() "Name1", "Name2", "Name3" ;
using var context = new dbconfig();
var topItem = context.DequeuePending(taskList);
我尝试将 DECLARE @list 作为 TaskTable;并收到同样的错误,所以我觉得我在这里遗漏了一些简单的东西。
【问题讨论】:
表提示应该在,好吧,表名/别名之后......另外还不清楚你是用create还是execute语句得到这个......如果create然后c#标签是不相关的 你要FROM InProgresses WITH (ROWLOCK, READPAST) INNER JOIN @tasklist AS t ON InProgresses.Task = t.Name
必须说:创造性地使用READPAST
和OUTPUT
,来实现一个并发队列。顺便说一句,你可以做一个DELETE TOP (1)
。如果没有结果,您可能需要循环它,这可能发生在每一行都被锁定的情况下。
【参考方案1】:
ON InProgresses.Task = @tasklist.Name
感觉跟这条线有点关系。
INNER JOIN @tasklist tl
ON InProgresses.Task = tl.Name
通常我会为有问题的表分配一个别名,以便稍后在查询中引用它。我对用户定义的表类型不是非常熟悉,所以如果上述建议不起作用,也许只是直接从该表中选择,看看那里的一切是否正常。
【讨论】:
以上是关于使用传入的字符串列表结合 SQL Server 存储过程 WITH LOCK 和 INNER JOIN的主要内容,如果未能解决你的问题,请参考以下文章
如何从 ASP.NET Core 将列表存储在 SQL Server 中?