Sql表检查

问题描述

我有一个表,其中包含以下字段 ID IDuser IDpc FROM TO。 显然,一台 PC 不能被多个用户在同一时间段内使用。我如何对条目施加约束以防止错误的条目? 我在 asp.net 中使用 sql Server 2016(管理工作室)

解决方法

好的,正如前面提到的,我虽然关于使用同一台 PC 的多个用户的部分与多用户数据库有关!

我现在看到您正在预订要使用的 PC,并且您不希望预订冲突。

好的,有一个非常简洁的条件来测试/检查预订冲突。

看起来像这样: 在以下情况下发生碰撞:

RequestStartDate <= EndDate 
and 
RequestEndDate >= StartDate 

如果值包括日期 + 时间,那么上述仍然可以正常工作。

上述条件会发现任何类型的重叠(因此中间的日期/时间)或任何重叠的部分。

正如我在评论中建议的那样?您可以获取/让数据库不允许您添加该行(您必须使用表触发器)。

但是,然后呢?

这真的暗示了什么?您不会写出记录并期望数据库出现故障。更糟糕的是,你真的想给用户一些不错的反馈。

因此,您的预订页面会询问房间,然后是开始/结束时间(带日期)。您使用上述条件,如果返回记录,则您告诉用户他们无法预订房间。但是,如果没有出现匹配项,则将该行添加到数据库中。

这种题其实看起来挺难的,但是有了上面的简单条件,却是异常的简单。

让我们将这个简单的例子作为一个 asp.net 网络表单。

因此,放入一个列表框、两个文本框(开始/结束)和一个书籍按钮。

因此,标记如下所示:

    <div style="margin-left:40px">
        <h2>Book a work station</h2>
        <div style="float:left">
            <h3>Select a work station</h3>
            <asp:ListBox ID="lstCompter" runat="server" 
                DataTextField="Computer" DataValueField="ID" Height="151px" Width="294px"></asp:ListBox>
        </div>

        <div style="float:left;margin-left:20px">
            <div style="float:left">
                <h3>Start Time</h3>
                <asp:TextBox ID="txtStart" runat="server" TextMode="DateTimeLocal"></asp:TextBox>
            </div>
            <div style="float:left;margin-left:20px">
                <h3>End Time</h3>
                <asp:TextBox ID="txtEnd" runat="server" TextMode="DateTimeLocal"></asp:TextBox>
            </div>
            <div style="clear:both;float:left;margin-top:40px">
                <asp:Button ID="cmdBook" runat="server" Text="Book Room" />
            </div>
            <div style="clear:both;float:left">
                <br />
                <asp:Label ID="lblMsg" runat="server" Text=""></asp:Label>
            </div>
        </div>
    </div>

我投入了几个 div 来布局。

好的,现在加载列表框的代码是这样的:

 Protected Sub Page_Load(ByVal sender As Object,ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then
        LoadData()
    End If

End Sub

Sub LoadData()

    Using cmdSQL As New SqlCommand("SELECT ID,Computer from Computers ORDER BY Computer",New SqlConnection(My.Settings.TEST4))
        cmdSQL.Connection.Open()
        lstCompter.DataSource = cmdSQL.ExecuteReader
        lstCompter.DataBind()
    End Using

End Sub

现在我们明白了:

enter image description here

请注意,如果您放入该文本框并在属性表中选择 DateTimeLocal 作为格式,那么无需任何额外代码,您就可以免费获得很酷的日期 = 时间选择器。

现在,让我们编写代码来检查我们是否可以预订。

用户选择一个房间,然后选择开始/结束时间(可以是 1 小时,也可以是 1 周 - 没关系。

所以,现在我们的图书按钮代码如下所示:

Protected Sub cmdBook_Click(sender As Object,e As EventArgs) Handles cmdBook.Click

    Dim strSQL As String
    strSQL = "SELECT * FROM Bookings WHERE IDPc = @IDpc " &
             "AND @RequestStart <= [TO] " &
             "AND @RequestEnd >= [From] "

    Using cmdSQL As New SqlCommand(strSQL,New SqlConnection(My.Settings.TEST4))

        cmdSQL.Parameters.Add("IDpc",SqlDbType.Int).Value = lstCompter.SelectedItem.Value
        cmdSQL.Parameters.Add("@RequestStart",SqlDbType.DateTime).Value = txtStart.Text
        cmdSQL.Parameters.Add("@RequestEnd",SqlDbType.DateTime).Value = txtEnd.Text

        cmdSQL.Connection.Open()
        Dim rstBooking As New DataTable
        rstBooking.Load(cmdSQL.ExecuteReader)

        If rstBooking.Rows.Count > 0 Then
            ' booking not allowed - show message
            lblMsg.Text = "Computer station already booked - try differnt date/time"
        Else
            ' add this booking
            Dim da As New SqlDataAdapter(cmdSQL)
            Dim daupdate As New SqlCommandBuilder(da)

            Dim OneRow As DataRow = rstBooking.Rows.Add
            OneRow("IDpc") = lstCompter.SelectedValue
            OneRow("IDUser") = LogOnID
            OneRow("From") = txtStart.Text
            OneRow("To") = txtEnd.Text
            da.Update(rstBooking)

            lblMsg.Text = "Room booked!"
        End If

    End Using


End Sub

注意这变得多么简单。我写这篇文章花了大约相同的时间?事实上,我有一个真正有效的预订页面。与上面的快速肮脏示例相比,它需要更多的关爱,但总而言之,上述方法的效果非常出色。

我们为列表框预订的计算机(桌子)是这样的:

enter image description here

然后预订表当然是这样的:

enter image description here

仅此而已。您可以看到我们查询了数据库,如果找到匹配项(冲突),那么我们甚至不会尝试添加该行,而是向用户提供该消息。

但是,如果现在找到了行,那么我们将该行添加到数据库中。

所以,它看起来像这样:

enter image description here

正是在这样的时刻,人们才意识到这在 asp.net 中是多么的简单。

享受吧!

仅供参考:“to”和“from”都是 SQL 词 - 你必须使用 [To] 和 [From](括号周围)这些词,因为 SQL Server 会混淆 - 这些列名是我们所说的保留单词 - 和“FROM”是常规 sql 语法的一部分,因此请记住在 sql 周围使用那些 []。