【问题标题】:Subquery returning more than 1 value in cursor in trigger子查询在触发器中的游标中返回超过 1 个值
【发布时间】:2014-04-15 18:56:59
【问题描述】:

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

[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

现在它适用于单行查询,但是当我尝试进行多行查询时(设置平装本 = 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 将数组中的值一一存储到 @var 中,从而允许您使用这些值。所以我猜select语句的正常使用是获取你需要更改的记录的主键。

【问题讨论】:

  • 表之间的JOIN 条件对我来说没有多大意义。你的表的主键是什么?
  • 您必须为此使用光标吗?无需任何光标即可轻松完成
  • @M.Ali 我会说是的,因为问题的开头是:所以这是学校作业,所以我必须使用带光标的触发器
  • 如果你在学校,你需要立即停止使用隐式连接,它们是一种 sql 反模式和一种非常糟糕的编程技术。在你的情况下,我不敢相信你真的想要那个特定的加入结果。当然,我也不尊重希望你在触发器中使用光标的老师,这是不应该发生的事情。
  • 是的,这就是为什么我问 OP 导师是否希望 OP 使用光标,或者它只是一个触发测试。

标签: sql-server-2008 triggers cursor subquery


【解决方案1】:

你的问题在这里:

set @b_code = (select book_code from deleted)

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

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

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 2021-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多