子查询在触发器中的游标中返回多于1个值

时间:2014-04-15 18:56:59

标签: sql-server-2008 triggers cursor subquery

所以这是一个学校作业,所以我必须使用光标触发器。我一直在反对这个问题太长时间了,并没有找到任何有用的东西。所以我有

的表格
[BOOK_CODE]
[TITLE]
[PUBLISHER_CODE]
[TYPE]
[PRICE]
[PAPERBACK]

我想要的是,当平装从1切换到0或0到1时,它会使价格加倍或减半。所以这是我的触发器:

ALTER trigger [dbo].[paper2Hard]
on [dbo].[BOOK]
after update
as
declare @done int;
declare @the_books varchar(255);
declare @b_code varchar(4)

/*This is suppose to grab all the rows that have had a change from 0 to 1 */

declare p2h cursor for 
select i.price from inserted i, deleted d 
where i.paperback > d.paperback;

/ *语法材料我不太明白* /

open p2h

/ 这是假设一次获得一行并将其粘贴到循环中 /

fetch p2h into @the_books
begin 
while @@fetch_status = 0
begin 

    /* This is suppose to get the book_code from the current row */

set @b_code = (select book_code from deleted)

    /*Then double the price while matching book_code to book_code */ 

update book 
set price = (price*2)
where book.book_code = @b_code

    /*Then go to the next one and keep doing it until they are all done*/

fetch next from p2h into @the_books 
end
close p2h
end

现在它适用于单行查询,但是当我尝试进行多行查询时(设置paperback = 1,其中book_code = x或book_code = y),它说:子查询返回的值超过1。子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时不允许这样做

我不明白它所指的是什么,如果你能指出我正确的方向,我将不胜感激。

好吧,我终于开始工作了,我明白我做错了什么。

declare @the_book varchar(4);

declare p2h cursor for 
select i.book_code from inserted i, deleted d 
where i.paperback > d.paperback;
open p2h
fetch p2h into @the_book

begin 
while @@fetch_status = 0
begin 
update book
set price = (price*2)
where book_code=@the_book
fetch next from p2h into @the_book 
end

我猜最大的问题是对游标是什么/它们如何工作的基本误解。因此,为了后代的利益,像我一样,很难解读文档的技术问题。

当您声明游标的名称并运行select语句时,它就像一个数组。然后,您可以使用fetch into @var逐个将值存储在数组中,从而允许您使用这些值。所以我想select语句的正常用法是获取你需要改变的记录的主键。

1 个答案:

答案 0 :(得分:0)

你的问题在这里:

set @b_code = (select book_code from deleted)

将inserted或deleted表的结果设置为标量变量永远不正确,因为它们可以包含多行。 SQL Server触发器不会逐行运行。您需要使用连接和变量。

您可能必须在课堂上学习这一点,但在现实生活中,您不应该考虑在触发器中使用光标,而在其他地方很少使用。