Sql table 检查
Sql table check
我有一个 table,其中包含以下字段 ID IDuser IDpc FROM TO。
显然,一台 PC 不能在同一时间段内被多个用户使用。我如何对条目施加约束以防止不正确的条目?
我使用 sql Server 2016 (management studio) 和 asp.net
好的,如前所述,我虽然关于多个用户使用同一台 PC 的部分与 multi-user 数据库有关!
我现在看到您正在预订要使用的 PC,您不希望预订冲突。
好的,test/check 有一个非常好的预订碰撞条件。
看起来像这样:
发生碰撞时:
RequestStartDate <= EndDate
and
RequestEndDate >= StartDate
如果值包括日期 + 时间,那么上面的方法仍然可以正常工作。
以上条件会发现任何类型的重叠(所以中间有一个 date/time)或任何重叠的部分。
正如我在评论中所建议的那样?您可以 get/have 数据库不允许您添加该行(您必须使用 table 触发器)。
然而,然后呢?
这到底意味着什么?您不会写出记录并期望数据库出现故障。更糟糕的是,你真的想给用户一些好的反馈。
因此,您的预订页面会询问房间,然后是 start/end 时间(带日期)。您使用上述条件,如果返回记录,则告诉用户他们无法预订房间。但是,如果没有匹配项出现,则将该行添加到数据库中。
这种题其实看起来挺难的,但事实证明加上上面简单的条件,还是非常简单的。
让我们把这个简单的例子作为 asp.net 网络表单来做。
因此,放入一个列表框、两个文本框 (start/end) 和一个图书按钮。
因此,标记如下所示:
<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
现在我们明白了:
请注意,如果您放入该文本框并在 属性 sheet 中选择 DateTimeLocal 作为格式,那么无需任何额外代码,您就可以免费获得酷炫的日期 = 时间选择器。
现在,让我们编写代码来检查我们是否可以预订。
用户选择一个房间,然后 start/end 次(可以是 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
注意这变得多么简单。大约在同一时间我写了这个post?事实上,我有一个真正有效的预订页面。它需要更多的爱和关怀,而不是像上面那样的快速肮脏的例子,但总而言之,上面的工作是非常了不起的。
我们的计算机 (table) 为列表框预订是这样的:
然后预订table当然是这样的:
就是这样。你可以看到我们查询数据库,如果我们找到匹配(冲突),那么我们甚至从不尝试添加行,我们给用户该消息。
但是,如果现在找到了行,那么我们会将行添加到数据库中。
所以,它看起来像这样:
正是在这样的时刻,人们才意识到 asp.net。
尽情享受吧!
仅供参考:“to”和“from”都是 SQL 词 - 你必须使用 [To] 和 [From](括号括起来)这些词,因为 SQL 服务器会得到混淆 - 这些列名是我们所说的保留字 - “FROM”是常规 sql 语法的一部分,所以请记住在 sql.
周围使用那些 []
我有一个 table,其中包含以下字段 ID IDuser IDpc FROM TO。 显然,一台 PC 不能在同一时间段内被多个用户使用。我如何对条目施加约束以防止不正确的条目? 我使用 sql Server 2016 (management studio) 和 asp.net
好的,如前所述,我虽然关于多个用户使用同一台 PC 的部分与 multi-user 数据库有关!
我现在看到您正在预订要使用的 PC,您不希望预订冲突。
好的,test/check 有一个非常好的预订碰撞条件。
看起来像这样: 发生碰撞时:
RequestStartDate <= EndDate
and
RequestEndDate >= StartDate
如果值包括日期 + 时间,那么上面的方法仍然可以正常工作。
以上条件会发现任何类型的重叠(所以中间有一个 date/time)或任何重叠的部分。
正如我在评论中所建议的那样?您可以 get/have 数据库不允许您添加该行(您必须使用 table 触发器)。
然而,然后呢?
这到底意味着什么?您不会写出记录并期望数据库出现故障。更糟糕的是,你真的想给用户一些好的反馈。
因此,您的预订页面会询问房间,然后是 start/end 时间(带日期)。您使用上述条件,如果返回记录,则告诉用户他们无法预订房间。但是,如果没有匹配项出现,则将该行添加到数据库中。
这种题其实看起来挺难的,但事实证明加上上面简单的条件,还是非常简单的。
让我们把这个简单的例子作为 asp.net 网络表单来做。
因此,放入一个列表框、两个文本框 (start/end) 和一个图书按钮。
因此,标记如下所示:
<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
现在我们明白了:
请注意,如果您放入该文本框并在 属性 sheet 中选择 DateTimeLocal 作为格式,那么无需任何额外代码,您就可以免费获得酷炫的日期 = 时间选择器。
现在,让我们编写代码来检查我们是否可以预订。
用户选择一个房间,然后 start/end 次(可以是 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
注意这变得多么简单。大约在同一时间我写了这个post?事实上,我有一个真正有效的预订页面。它需要更多的爱和关怀,而不是像上面那样的快速肮脏的例子,但总而言之,上面的工作是非常了不起的。
我们的计算机 (table) 为列表框预订是这样的:
然后预订table当然是这样的:
就是这样。你可以看到我们查询数据库,如果我们找到匹配(冲突),那么我们甚至从不尝试添加行,我们给用户该消息。
但是,如果现在找到了行,那么我们会将行添加到数据库中。
所以,它看起来像这样:
正是在这样的时刻,人们才意识到 asp.net。
尽情享受吧!
仅供参考:“to”和“from”都是 SQL 词 - 你必须使用 [To] 和 [From](括号括起来)这些词,因为 SQL 服务器会得到混淆 - 这些列名是我们所说的保留字 - “FROM”是常规 sql 语法的一部分,所以请记住在 sql.
周围使用那些 []