无法更新所需的行

时间:2018-02-08 11:25:43

标签: c# mysql sql .net database

我有以下查询,它通过C#在单个字符串中执行。

   SET @out_param := '';
    SELECT 
        sightinguid
    FROM
        pc
            INNER JOIN
        c ON uid = id
    WHERE
        //... other conditions
            AND (@out_param:=CONCAT_WS(',', sightinguid, @out_param))
    LIMIT 50 FOR UPDATE;
    UPDATE pc
    SET 
        last_accessed_timestamp = NOW()
    WHERE
        sightinguid IN (@out_param);
    SELECT @out_param;

我基本上试图将第一个查询的前50个值放在逗号分隔的字符串中,并在结尾处返回此字符串。在这样做之前,我希望update语句在那些相同的记录上执行。但是,只有第一个瞄准者正在更新。当我对sightinguid IN (@out_param)部分中的多个值进行硬编码时,它会工作并全部更新 - 所以我假设该部分有问题。

由于SELECT部分,我不能将LIMIT 50放在子查询中并从那里更新,因为MySQL不允许在子查询中放置LIMIT。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

正如你所说,我不知道你是否可以像这样使用IN,即使用变量。 无论如何,一个简单的解决方法是使用临时表来存储两个查询之间的信息:

CREATE TEMPORARY TABLE temp(
   sightinguid #typeofsightinguid 
)  

INSERT INTO temp
SELECT //select1
    sightinguid
FROM
    pc
        INNER JOIN
    c ON uid = id
WHERE
    //... other conditions
    AND (@out_param:=CONCAT_WS(',', sightinguid, @out_param))
LIMIT 50 FOR UPDATE;

UPDATE pc
SET 
    last_accessed_timestamp = NOW()
WHERE
    sightinguid IN (SELECT sightinguid FROM temp);

DROP TABLE temp;
SELECT @out_param;

如果临时表不是一个选项(无论什么原因),那么你将不得不做一些像建议的herehere这样的事情:基本上,限制子查询的子查询。像:

UPDATE pc
SET 
    last_accessed_timestamp = NOW()
WHERE
    sightinguid IN (
        SELECT sightinguid FROM (
            SELECT //select2
               sightinguid 
            FROM pc
            INNER JOIN c 
            ON uid = id
            WHERE //... other conditions
            LIMIT 50
        ) tmp
     )

另外,还有一件事需要注意,我之前忘记提及:使用LIMIT而不使用ORDER BY会导致非确定性查询,即具有不同的行顺序。因此,按照我写的示例,您 COULD select1select2上获得2个不同的结果集。