所以这真的很奇怪。
我在sqlserver上用.net运行一个带有'Select Count(*)'的sql命令,得到一个像“Needs attention CA”这样的响应(它位于内部连接表的一个记录的一个字段的varchar中)
咦? Count(*)如何返回一个字符串?这段代码正确执行1000次中的999次。有时在某些客户端服务器上,它会抛出一串错误一小时左右才会奇迹般地再次停止。
这是我的sqlcommand:
SELECT Count(*)
FROM patientsappointments
INNER JOIN appointmenttypes
ON patientsappointments.appointmenttypeid =
appointmenttypes.appointmenttypeid
WHERE ( ( patientsappointments.date > @WeekStartDate
AND patientsappointments.date < @WeekFinishDate )
AND ( patientsappointments.status = 'Pending' )
AND ( patientsappointments.doctorid = @DoctorID )
AND ( appointmenttypes.appointmentname <> 'Note' ) )
这些是参数:
@WeekStartDate = 24/06/2013 12:00:00 AM (DateTime)
@WeekFinishDate = 1/07/2013 12:00:00 AM (DateTime)
@DoctorID = 53630c67-3a5a-406f-901c-dbf6b6d1b20f (UniqueIdentifier)
我执行sqlcmd.executescalar来获取结果。有什么想法吗?
实际执行的代码是:
SyncLock lockRefresh
Dim WeekFulfilled, WeekPending As Integer
Using conSLDB As New SqlConnection(modLocalSettings.conSLDBConnectionString)
Dim mySQL As SqlCommand
mySQL = New SqlCommand("SELECT COUNT(*) FROM PatientsAppointments INNER JOIN AppointmentTypes ON PatientsAppointments.AppointmentTypeID = AppointmentTypes.AppointmentTypeID " & _
"WHERE ((PatientsAppointments.Date > @WeekStartDate AND PatientsAppointments.Date < @WeekFinishDate) AND (PatientsAppointments.Status = 'Pending') " & _
"AND (PatientsAppointments.DoctorID = @DoctorID) AND (AppointmentTypes.AppointmentName <> 'Note'))", conSLDB)
Try
mySQL.Parameters.Add("@WeekStartDate", SqlDbType.DateTime).Value = MonthCalendar1.SelectionStart.Date.AddDays(-MonthCalendar1.SelectionStart.Date.DayOfWeek).AddDays(1)
mySQL.Parameters.Add("@WeekFinishDate", SqlDbType.DateTime).Value = MonthCalendar1.SelectionStart.Date.AddDays(-MonthCalendar1.SelectionStart.Date.DayOfWeek).AddDays(8)
mySQL.Parameters.Add("@DoctorID", SqlDbType.UniqueIdentifier).Value = cboDoctors.SelectedValue
conSLDB.Open()
'got errors here like "Conversion from string "R2/3" to type 'Integer' is not valid." Weird.
'failing on deadlock - maybe due to simultaneous updating from udp event. Try adding random delay to refresh
WeekPending = mySQL.ExecuteScalar
Catch ex As Exception
ErrorSender.SendError("frmAppointmentBook - RefreshHeader 1", ex, New String() {String.Format("mySQL.commandtext: {0}", mySQL.CommandText), _
String.Format("mySQL.Parameters: {0}", clsErrorSender.ParamsListToString(mySQL.Parameters))})
End Try
Me.lblPendingWeek.Text = WeekPending
Try
mySQL.CommandText = "SELECT COUNT(*) FROM PatientsAppointments INNER JOIN AppointmentTypes ON PatientsAppointments.AppointmentTypeID = AppointmentTypes.AppointmentTypeID WHERE " & _
"(PatientsAppointments.Date > @WeekStartDate AND PatientsAppointments.Date < @WeekFinishDate) AND (PatientsAppointments.Status = 'Fulfilled') AND " & _
"(PatientsAppointments.DoctorID = @DoctorID) AND (AppointmentTypes.AppointmentName <> 'Note')"
'didn't get the error here... but just in case...
WeekFulfilled = mySQL.ExecuteScalar
Catch ex As Exception
ErrorSender.SendError("frmAppointmentBook - RefreshHeader 2", ex, New String() {String.Format("mySQL.commandtext: {0}", mySQL.CommandText)})
End Try
conSLDB.Close()
End Using
End SyncLock
确切的错误消息是:
System.InvalidCastException
Conversion from string "Needs Attention DC" to type 'Integer' is not valid.
答案 0 :(得分:2)
您的问题与代码的COUNT(*)
部分无关。问题出在查询中的其他位置。这个特定错误告诉你的是,在某些时候你正在将一个字符字段(它可能通常包含数字)与一个整数字段进行比较。字符字段的值之一恰好是“Needs Attention DC
”。如果我不得不猜测它可能是patientsappointments.appointmenttypeid
或appointmenttypes.appointmenttypeid
。仔细检查每个列的数据类型,确保它们实际上是INT
。如果它们都是INT
,那么请开始检查查询中其他明确命名的列,看看您是否有任何意外。
答案 1 :(得分:1)
您的实施中某处必须出错...
Per the documentation,count始终返回 int 数据类型值。
答案 2 :(得分:0)
我要再做一次猜测。我猜这是一个多线程问题。您可能正在共享多个线程之间的连接。偶尔,线程将从其他地方获取该人并执行它。确保连接变量是本地的,并且一次只能有一个线程访问它。
正如马丁指出的那样,以下答案是错误的。我在这里保留这个以表明这是错误的。
根据每个人的说法,您的列上存在类型不匹配。既然你的where子句似乎没问题,你的联系也没问题,那么它必须在其他地方。我会检查一下患者的预约或预约是否是观点。也许视图有一个抛出异常的连接。检查所有联接的模式定义/位置。在那里的某个地方,你将整数存储在一个字符字段中。这对大多数行都很好,但其中一行有你的字符串。
如果它不在你的视图中,它可能是某个地方的触发器。关键在于某处存在架构不匹配。找到架构不匹配后,可以通过查询该字符串找到该行。
答案 3 :(得分:0)
由于这并不总是发生,因此它必须是发送的其中一个参数值的结果。这是使用动态SQL的lbuiggest问题之一。我要做的是创建动态SQl,然后将其存储在数据库记录表中,其中包含日期和时间以及执行它的用户。然后,当您获得异常时,您可以找到发送的确切SQL代码。您很可能需要对输入变量进行更多控制,以确保放在其中的数据具有正确的数据类型。