0

所以这真的很奇怪。

我在 sqlserver 上使用 'Select Count(*)' 从 .net 运行 sql 命令,并得到类似“需要注意 CA”的响应(位于内部连接表的一个记录的一个字段的 varchar 中)。

嗯?Count(*) 如何返回字符串?此代码在 1000 次中正确执行了 999 次。只是有时在某些客户端服务器上,它会抛出一个小时左右的一系列错误,然后奇迹般地再次停止。

这是我的sql命令:

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.
4

4 回答 4

2

COUNT(*)您的问题与您的代码部分无关。问题出在您查询的其他地方。该特定错误告诉您的是,有时您正在将字符字段(它可能通常包含数字)与整数字段进行比较。字符字段的值之一恰好是“ Needs Attention DC”。如果我不得不猜测它可能是patientsappointments.appointmenttypeid或者appointmenttypes.appointmenttypeid。仔细检查每一列的数据类型,以确保它们确实是INT. 如果它们都是,INT则开始检查查询中其他显式命名的列,看看是否有任何意外。

于 2013-06-25T11:47:36.820 回答
1

您的实施中一定有错误......

根据文档,count 总是返回一个int数据类型值。

于 2013-06-25T10:03:26.010 回答
0

由于这并不总是发生,它必须是传入的参数值之一的结果。这是使用动态 SQL 的最大问题之一。我要做的是创建动态 SQl,然后将其存储在数据库日志表中,其中包含日期和时间以及执行它的用户。然后,当您收到异常时,您可以找到发送的确切 SQL 代码。您很可能需要对输入变量进行更多控制,以确保放入其中的数据属于正确的数据类型。

于 2013-06-25T14:21:05.830 回答
0

我要再做一个猜测。我猜这是一个多线程问题。您可能正在多个线程之间共享连接。偶尔,线程会从其他地方得到那个人并执行它。确保连接变量是本地的,并且一次只有一个线程可以访问它。

正如马丁指出的那样,以下答案是错误的。我把它放在这里是为了表明这是错误的。

从每个人已经说过的内容来看,您的列上存在类型不匹配。由于您的 where 子句似乎很好,并且您的连接很好,它必须在其他地方。我会检查患者约会或约会类型是否是视图。也许视图有一个抛出异常的连接。检查所有连接/位置的架构定义。在那里的某个地方,您将整数存储在字符字段中。大多数行都可以,但其中之一有你的字符串。

如果它不在您的观点中,它可能是某个地方的触发器。关键是某处存在模式不匹配。发现架构不匹配后,您可以通过查询该字符串来找到该行。

于 2013-06-25T12:47:31.927 回答