使用传入的字符串列表结合 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 必须说:创造性地使用READPASTOUTPUT,来实现一个并发队列。顺便说一句,你可以做一个DELETE TOP (1)。如果没有结果,您可能需要循环它,这可能发生在每一行都被锁定的情况下。 【参考方案1】:

ON InProgresses.Task = @tasklist.Name

感觉跟这条线有点关系。

INNER JOIN @tasklist tl
      ON InProgresses.Task = tl.Name

通常我会为有问题的表分配一个别名,以便稍后在查询中引用它。我对用户定义的表类型不是非常熟悉,所以如果上述建议不起作用,也许只是直接从该表中选择,看看那里的一切是否正常。

【讨论】:

以上是关于使用传入的字符串列表结合 SQL Server 存储过程 WITH LOCK 和 INNER JOIN的主要内容,如果未能解决你的问题,请参考以下文章

sql server 分组查询结合日期模糊查询

SQL Server 以字符串列表开头

如何从 ASP.NET Core 将列表存储在 SQL Server 中?

在 SQL Server 中检查逗号分隔字符串中是不是存在子字符串的最有效方法

使用列表更新 SQL Server 数据库

MS SQL Server 在空格上拆分单词,但仅在不在双引号中时