DB2SQL尝试使用函数创建触发器(计算天数)

时间:2017-10-01 09:53:27

标签: sql db2

所以现在,我创建了2个表,Booking和BookingDetails,当我输入BookingDetails的详细信息时,我想创建一个触发器,它将自动更新Booking表中的总日期。以下是我的代码:

BookingDetails:

create table BookingDetail ( 
BD_ID int primary key not null, 
Date_In date, 
Date_Out date, 
BK_ID int, 
Room_ID int,
foreign key(BK_ID) references Booking(BK_ID),  
foreign key(Room_ID) references Room(Room_ID)
)

还有预订

create table Booking ( 
BK_ID int primary key not null, 
BK_Date Date, 
BK_TotalDays int, 
BK_PayStatus char(6), 
Cus_ID int, 
Emp_ID int,
foreign key(Cus_ID) references customer(Cus_ID),  
foreign key(Emp_ID) references Employee(Emp_ID)
)

创建了功能和触发器:

create function countdays(t1 date, t2 date)
returns INT
return (timestampdiff(16, char(timestamp(t2) - timestamp(t1))))

create trigger totaldays
after insert on bookingdetail
referencing new as n
for each row mode db2sql
update booking
set bk_totaldays = 
countdays((select date_in from bookingdetail), (select date_out from 
bookingdetail))
where booking.bk_id = n.bk_id;

执行这些语法没有问题,但是当我尝试在预订详细信息中输入新记录以让触发器在预订中触发时,发生错误,请问为什么?提前谢谢。

2 个答案:

答案 0 :(得分:1)

查看SQL错误提供的信息:

set.seed(123)
#df1 <- data.frame(ID=sample(letters[1:6],10,replace=TRUE)) #This one has repeated IDs
df1 <- data.frame(ID=letters[1:6])
df2 <- data.frame(
  ID1 = letters[1:2],
  ID2 = letters[3:4],
  ID3 = letters[5:6],
  V1 = c(23.32,21.24),
  V2 = c(45.32,47.21)
)

library(dplyr)
#> Warning: package 'dplyr' was built under R version 3.4.2
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
df <- bind_rows(df2 %>% select(ID=ID1, V1, V2),
                df2 %>% select(ID=ID2, V1, V2),
                df2 %>% select(ID=ID3, V1, V2)) %>% 
      right_join(df1)
#> Warning in bind_rows_(x, .id): Unequal factor levels: coercing to character
#> Warning in bind_rows_(x, .id): binding character and factor vector,
#> coercing into character vector

#> Warning in bind_rows_(x, .id): binding character and factor vector,
#> coercing into character vector

#> Warning in bind_rows_(x, .id): binding character and factor vector,
#> coercing into character vector
#> Joining, by = "ID"
#> Warning: Column `ID` joining character vector and factor, coercing into
#> character vector
df
#>   ID    V1    V2
#> 1  a 23.32 45.32
#> 2  b 21.24 47.21
#> 3  c 23.32 45.32
#> 4  d 21.24 47.21
#> 5  e 23.32 45.32
#> 6  f 21.24 47.21

因此,这部分触发器表达式返回的行数超过1行

db2 ? SQL0811
SQL0811N  The result of a scalar fullselect, SELECT INTO statement, or
  VALUES INTO statement is more than one row.

修复此问题以返回单行。

答案 1 :(得分:0)

@MichaleTiefenbacher关于错误的原因是正确的,但他对如何处理它是错误的。让我们再看看你的触发器:

create trigger totaldays
after insert on bookingdetail
referencing new as n -- wait, what's this?
for each row mode db2sql
update booking
set bk_totaldays = 
countdays((select date_in from bookingdetail), (select date_out from bookingdetail))
where booking.bk_id = n.bk_id;

您可以参考刚插入的值!使用FOR EACH ROW时,表格引用NEW引用刚刚插入的单数行。因此,您甚至不需要查看完整的表格,只需使用您刚才使用的内容:

create trigger totaldays
after insert on bookingdetail
referencing new as n 
for each row mode db2sql
update booking
set bk_totaldays = countdays(n.date_in, n.date_out)
where booking.bk_id = n.bk_id;

(正如我在对你的问题的评论中提到的,你可能想要改变计算日期的方式,但这与此无关)