سؤال

السلسلة التي تم تمريرها إلى وظيفتي المخصصة هي ما يلي:

SELECT key FROM ubis WHERE MemberID = '144'
AND To >='11/7/2009 9:11:23 pm'
AND From <= '11/7/2009 9:11:23 pm'

    Public Shared Function GetDataTable(ByVal CmdText As String) As DataTable
        Dim myConn As New SqlConnection(ConfigurationManager.ConnectionStrings("Conn").ConnectionString)
        Dim myCmd As New SqlCommand(CmdText, myConn)
        myConn.Open()
        Dim myReader As SqlDataReader = myCmd.ExecuteReader()
        Dim myTable As New DataTable()
        myTable.Load(myReader)
        myConn.Close()
        Return (myTable)
    End Function

وهنا الخطأ الذي أحصل عليه، فشل التحويل عند تحويل DETETIME من سلسلة الأحرف

أفهم أن حقول DateTime مرت كسلسلة في الوظيفة، ولكن ما هي الخيارات التي لدي؟

هل كانت مفيدة؟

المحلول

هل حاولت تشغيل SQL في Studio Management ورؤية ما يحدث؟

نصائح أخرى

هل فكرت في استخدام استعلام معلمات؟ هذا من شأنه أن يحل مشكلتك، وإعطاء الأمن المضافة في القضية التي WHERE يتم أخذ الشروط من إدخال المستخدم.

مثال (vb.net):

Dim myCmd As New SqlCommand(CmdText, myConn)
myCmd.Parameters.AddWithValue("MemberID", 144)
myCmd.Parameters.AddWithValue("Timestamp", DateTime.Now)

يستخدم مع نص الاستعلام هذا (SQL):

SELECT key FROM ubis WHERE MemberID = @MemberID
AND @Timestamp BETWEEN From AND To

خارج الموضوع: BETWEEN الكلمة الرئيسية في SQL هي مجرد طريقة أنيقة للتعبير عن >= AND <= الظروف.

هذه الروائح من مشكلة عدم حصانة حقن SQL. هذا التاريخ لم يحدث أي فرصة من المستخدم (حتى بشكل غير مباشر)، فعل ذلك؟ حتى إذا كان هذا واحد آمن، فإن الوظائف العامة مثل "getdatatable ()" لا تحسب معلمات الاستعلام الجيدة دائما خطأ.

تريد شيئا أكثر مثل هذا:

Public Shared Function GetMemberKeys(ByVal MemberID As Integer, ByVal KeyDate As DateTime) As DataTable

    Static sql As String= _
         "SELECT key" _
      + " FROM ubis" _ 
      + " WHERE MemberID= @MemberID AND @KeyDate BETWEEN [FROM] AND [TO]"

    Dim dt As New DataTable()
    Using cn As New SqlConnection(ConfigurationManager.ConnectionStrings("Conn").ConnectionString), _
          cmd As New SqlCommand(sql, cn)

        cmd.Parameters.Add("@MemberID", SqlDbType.Int).Value = MemberID
        cmd.Parameters.Add("@KeyDate", SqlDbType.DateTime).Value = KeyDate

        cn.Open()
        Using rdr As SqlDataReader = cmd.ExecuteReader()
             dt.Load(rdr)
        End Using
    End Using
    Return dt
End Function

11/7/2009 غامض - هل 11 يوليو أو 7 نوفمبر؟

SQL ليس لديه طريقة لمعرفة - وهذا يعتمد على الإعدادات الافتراضية التي تم إعدادها معها. سيكون من الأفضل أن تمر في التاريخ بتنسيق لا لبس فيه:

SELECT key FROM ubis WHERE MemberID = '144' 
               AND To >='11 July 2009 9:11:23 pm' 
               AND From <= '11 July 2009 9:11:23 pm'

بدلا من ذلك، استخدم التحويل الصحيح مع الصحيح تنسيق رمز, أو أ مخصص واحد, ، كما اقترح بواسطة Zyphrax:

SELECT key FROM ubis WHERE MemberID = '144'
       AND To >= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)
       AND From <= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)

يمكنك استخدام الأمر Convert لتحويل Char إلى DateTime.

SELECT key FROM ubis WHERE MemberID = '144'
           AND To >= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)
           AND From <= CONVERT(datetime, '11/7/2009 9:11:23 pm', 105)

لست متأكدا من 105، قد تضطر إلى Google للحصول على رمز التنسيق الصحيح.

بالإضافة إلى ذلك إذا واجه رمز SQL الخاص بك استثناء، فلن يتم إغلاق اتصالك. قد ترغب في إضافة القليل من استخدام التعليمات البرمجية لإصلاح هذا.

Public Shared Function GetDataTable(ByVal CmdText As String) As DataTable        
 Using myConn As New SqlConnection(ConfigurationManager.ConnectionStrings("Conn").ConnectionString)
   Using myCmd As New SqlCommand(CmdTxt, myConn)
     conn.Open()
       Using myReader As SqlDataReader = myCmd.ExecuteReader()
           Dim myTable As New DataTable()
           myTable.Load(myReader)
           myConn.Close()
           Return (myTable)  
      End Using
     End Using
End Function
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top