一个保龄球运动员不能连续两次在板球场上摔倒

时间:2017-09-20 06:16:05

标签: sql-server database check-constraints

我正在研究板球项目。我有一个表OverDetails。我想在此表中插入数据。

ID  OverNumber  BowlerID  InningsID
1       1          150          1
2       4          160          1
3       3          165          1
4       2          150          1

Row_1Row_2Row_3是合法的。 Row_4不合法,因为一个投球手不能在一局中连续两次投球。没有必要在数据库中连续添加过量。

我在SQL Server中添加了一个约束。

#Constraint_1

ALTER TABLE OverDetails ADD CONSTRAINT UniqueOverInInning 
UNIQUE(OverNumber, BowlerID, IninngsID);

这种约束非常有效。

我需要这样的支票:

#Constraint_2

ALTER TABLE OverDetails ADD CONSTRAINT UniqueConsecutiveBowlerInOneInning 
CHECK (OverNumber + 1 != OverNumber and BowlerID + 1 != BowlerID 
         and IninngID + 1 != IninngID)

3 个答案:

答案 0 :(得分:1)

你需要一个从给定的InningID中返回最后一个BowlerID的函数:

    CREATE FUNCTION dbo.GetBowlerID
        ( @InningId INT, @OverNumber INT, @BowlerID INT)
        RETURNS INT
        AS
        BEGIN
        RETURN (SELECT top 1 CASE WHEN
(SELECT BowlerID
    FROM OverDetails 
    WHERE InningsId = @InningId AND OverNumber = @OverNumber - 1 ) = @BowlerID
OR
(SELECT BowlerID
    FROM OverDetails 
    WHERE InningsId = @InningId AND OverNumber = @OverNumber + 1 ) = @BowlerID
THEN 1 else 0 end)
        END

然后你可以把它放入检查约束中:

ALTER TABLE OverDetails ADD CONSTRAINT UniqueConsecutiveBowlerInOneInning 
  CHECK (dbo.GetBowlerID(InningsId, OverNumber, BowlerID)=0)

答案 1 :(得分:1)

检查约束不能直接引用其他数据。有一些技术试图使用UDF来解决这个限制,但它们往往效果不好。特别是在这种情况下我假设第4行的插入应该如果它的bowlerID为165则会被阻止,因为这意味着超过2&3会共用一个投球手。

相反,我们可以使用一对视图来实现它。我通常把DRI放在像这样的视图名称的某个地方,以表明它们是出于声明性参照完整性的原因,而不是因为我打算让人们查询它们。

create table dbo.Bowling (
    ID int not null,
    OverNumber int not null,
    BowlerID int not null,
    InningsID int not null,
    constraint PK_Bowling PRIMARY KEY (ID),
    constraint UQ_Bowling_Overs UNIQUE (OverNumber,InningsID)
)
go
create view dbo.Bowling_DRI_SuccessiveOvers_Odd
with schemabinding
as
    select
        (OverNumber/2) as OddON,
        BowlerID
    from
        dbo.Bowling
go
create unique clustered index UQ_Bowling_DRI_SuccessiveOvers_Odd on dbo.Bowling_DRI_SuccessiveOvers_Odd (OddON,BowlerID)
go
create view dbo.Bowling_DRI_SuccessiveOvers_Even
with schemabinding
as
    select
        ((OverNumber+1)/2) as EvenON,
        BowlerID
    from
        dbo.Bowling
go
create unique clustered index UQ_Bowling_DRI_SuccessiveOvers_Even on dbo.Bowling_DRI_SuccessiveOvers_Even (EvenON,BowlerID)
go
insert into dbo.Bowling(ID,OverNumber,BowlerID,InningsID) values
(1,1,150,1),
(2,4,160,1),
(3,3,165,1)
go
insert into dbo.Bowling(ID,OverNumber,BowlerID,InningsID) values
(4,2,150,1)

此最终插入会生成错误:

  

消息2601,级别14,状态1,行37无法插入重复的键行   在对象&#d ;.Bowling_DRI_SuccessiveOvers_Even'具有独特的索引   ' UQ_Bowling_DRI_SuccessiveOvers_Even&#39 ;.重复键值为(1,   150)。声明已经终止。

希望你可以看到我用来制作这些视图的技巧来检查你想要的约束 - 它的设置是为了让行与它们配对(逻辑,基于OrderNumber )继承者或前任者基于使用整数数学将OrderNumber除以2。

然后,我们对这些对应用唯一约束,包括BowlerID。只有当相同的投球手连续两次投球时,我们才会生成多个具有相同(OddON / EvenON)和BowlerID值的行。

答案 2 :(得分:0)

也许这个?

workbook=new HSSFWorkbook();
        HSSFSheet Sheet=workbook.createSheet("List Order Details");
        Row rowHeading=Sheet.createRow(0);
         rowHeading.createCell(0).setCellValue("Invoice ID");
         rowHeading.createCell(1).setCellValue("Food Court Name");
         rowHeading.createCell(2).setCellValue("Food Stall Name");
         rowHeading.createCell(3).setCellValue("Customer Name");
         rowHeading.createCell(4).setCellValue("Total Price");
         rowHeading.createCell(5).setCellValue("order status");
         rowHeading.createCell(6).setCellValue("Delivery Location");
         rowHeading.createCell(7).setCellValue("Delivery Date");
         rowHeading.createCell(8).setCellValue("Delivery Time");
         for(int i=0;i<9;i++){
             CellStyle stylerrowHeading=workbook.createCellStyle();
             HSSFFont font=workbook.createFont();
             font.setBold(true);
             font.setFontName(HSSFFont.FONT_ARIAL);
             font.setFontHeightInPoints((short)11);
             stylerrowHeading.setFont(font);
             stylerrowHeading.setVerticalAlignment(CellStyle.ALIGN_CENTER);
            rowHeading.getCell(i).setCellStyle( stylerrowHeading);
            }
            if (null == excelList)
                  return null;
            int r=1;
        Row row=Sheet.createRow(r++);
                //id coloumn
                Cell cellId=(Cell) row.createCell(0);
                orderDO.setId(String.valueOf(orderEntity.getId()));
                cellId.setCellValue(""+orderEntity.getId());
                 r++;

                //foodstall name
                 Cell cellStallName=(Cell) row.createCell(2);
                cellStallName.setCellValue(foodStallEntity.getName());
                r++;
                //foodCourtname
                Cell cellCourtName=(Cell) row.createCell(1);
                 cellCourtName.setCellValue(foodCourtEntity.getName());
                //customername
                Cell cellCustomerName=(Cell) row.createCell(3);
            cellCustomerName.setCellValue(customerEntity.getName());
                r++;
                //total price
                Cell cellTotalPrice=(Cell) row.createCell(4);
                                     CellStyle styleprice=workbook.createCellStyle();
                 HSSFDataFormat cf=workbook.createDataFormat();
                 styleprice.setDataFormat(cf.getFormat(" $#,##0.00"));
                 cellTotalPrice.setCellStyle(styleprice);
                //orderstatus
                Cell cellOrderStatus=(Cell) row.createCell(5);
                orderDO.setStatus(OrderStatusDTO.valueOf(orderEntity.getOrderstatus()));
                 cellOrderStatus.setCellValue(orderEntity.getOrderstatus());

                //deliveryLocation
                Cell cellBuilding=(Cell) row.createCell(6);
                DeliveryLocationEntity deliveryLocationEntity = deliveryLocationRepository
                        .findById(orderEntity.getDeliverylocationid());
                orderDO.setDeliveryBuilding(deliveryLocationEntity.getBuilding());
              cellBuilding.setCellValue(deliveryLocationEntity.getBuilding());

                //deliverydate
                Cell cellDeliveryDate=(Cell) row.createCell(7);
                String s1 = String.valueOf(orderEntity.getOrderDate());
                orderDO.setOrderDate(s1.substring(0, 10));

                cellDeliveryDate.setCellValue(orderEntity.getOrderDate());
                 CellStyle styleCreationDate=workbook.createCellStyle();
                 HSSFDataFormat dfCreationDate=workbook.createDataFormat();
                 styleCreationDate.setDataFormat(dfCreationDate.getFormat(" m/d/yy"));
                 cellDeliveryDate.setCellStyle(styleCreationDate);

                //deliverytime
                Cell cellDeliveryTime=(Cell) row.createCell(8);
                orderDO.setDeliveryTime(orderEntity.getDeliverytime());
                cellDeliveryTime.setCellValue(orderEntity.getDeliverytime());

                for(int i=0;i<9;i++)
                Sheet.autoSizeColumn(i);
                        FileOutputStream out=new FileOutputStream(new File("attachment; filename=listproducts.xls"));
                        //response.setHeader("Content-disposition", "attachment; filename=listproducts.xls");
                        workbook.write(out);
                        out.close();
                        workbook.close();
                        System.out.println("data enter Sucessfully...");



    } catch (Exception e) {
        // TODO: handle exception
        System.out.println(e.getMessage());
    }
    return workbook;

}