Update语句适用于临时表,但不适用于表值变量

时间:2017-05-22 18:58:58

标签: sql sql-server tsql correlated-subquery rdl

我定义了这个表:

CREATE TABLE #stagingtable
(
    id int identity(1,1),
    typeflag int default 0,
    resourcetype varchar(25),
    resource varchar(40),
    est int,
    planned int,
    actual int
)

And then I am looking for places where the resourcetype is not the same as the resourcetype in the previous row, so I wrote the following UPDATE:

UPDATE #stagingtable
SET typeflag = 1 
WHERE id = (
    SELECT min(id)
    FROM #stagingtable
)
OR resourcetype <> (
    SELECT resourcetype
    FROM #stagingtable rt2
    WHERE rt2.id = (
        SELECT MAX(id) 
        FROM #stagingtable rt3
        WHERE rt3.id < #stagingtable.id
    )
)

这完美无缺。但是,我所处的环境不允许我使用临时表(RDL!)。所以我将表格改为表值变量:

DECLARE @stagingtable TABLE
(
    id int identity(1,1),
    typeflag int default 0,
    resourcetype varchar(25),
    resource varchar(40),
    est int,
    planned int,
    actual int
)

But the following code doesn't work. 

UPDATE @stagingtable
SET typeflag = 1 
WHERE id = (
    SELECT min(id)
    FROM @stagingtable
)
OR resourcetype <> (
    SELECT resourcetype
    FROM @stagingtable rt2
    WHERE rt2.id = (
        SELECT MAX(id) 
        FROM @stagingtable rt3
        WHERE rt3.id < @stagingtable.id
    )
)

我收到消息:

  

Msg 137,Level 16,State 1,Line 431必须声明标量变量   &#34; @ stagingtable&#34;

有没有办法更改更新语句以使其有效?

2 个答案:

答案 0 :(得分:5)

您的查询几乎没问题。您只需要在最后一行通过您给出的别名引用表变量:

  

WHERE rt3.id < @stagingtable.id

DECLARE @stagingtable TABLE
(
    id int identity(1,1),
    typeflag int default 0,
    resourcetype varchar(25),
    resource varchar(40),
    est int,
    planned int,
    actual int
)


UPDATE @stagingtable
SET typeflag = 1 
WHERE id = (
    SELECT min(id)
    FROM @stagingtable
)
OR resourcetype <> (
    SELECT resourcetype
    FROM @stagingtable rt2
    WHERE rt2.id = (
        SELECT MAX(id) 
        FROM @stagingtable rt3
        WHERE rt3.id < rt2.id
    )
)

答案 1 :(得分:1)

我设法提出了正确的语法,即在变量名称周围添加方括号:

UPDATE @stagingtable
SET typeflag = 1 
WHERE id = (
    SELECT min(id)
    FROM @stagingtable
)
OR resourcetype <> (
    SELECT resourcetype
    FROM @stagingtable rt2
    WHERE rt2.id = (
        SELECT MAX(id) 
        FROM @stagingtable rt3
        WHERE rt3.id < [@stagingtable].id
    )
)