วันพฤหัสบดีที่ 2 ตุลาคม พ.ศ. 2557

การใช้ Prepared Statements


1. การเขียนแบบ prepared statatments จะช่วยให้ผู้เขียนโปรแกรมมั่นใจได้ว่าจะไม่มีปัญหา SQL Injection ยกตัวอย่างเช่น การ ยัด string   '  เช่น it's a book  จะไม่สามารถทำได้


2. ารเขียนแบบ prepared statatments จะช่วยในเรื่องของ  Performance  จะดีกว่าการเขียน query หรือ การ Insert Update โดยส่งค่าให้แบบตรงๆ เช่น String name="name001";

String sql="select * from user where username='"+name+" ' ";

Performance ของ prepared  ดีอย่างไร ????
เริ่มต้นคือ ปกติแล้ว db ไม่ได้ทำงานด้วยภาษา SQL ตรงๆครับ แต่จะมีการ compile ก่อนเพือเอาไปรันในตัว db engine อีกที และถ้าเป็น statement ธรรมดาทุกๆๆ exec command จะถูก compile ใหม่ทุกรอบ แต่ถ้าหากเป็น Prepared Statement เวลาใช้คือมันจะสร้างทุกอย่างไว้พร้อมแล้วแล้วเราก็แค่ส่ง data เพือไป execute ซํ้าๆๆ ไปเรือยๆๆ หรืออธิบายง่ายคือ db engine จะมีการ catch command ที่ได้จาก compile sql เอาไว้

สำหรับการใช้ prepare statements
SELECT * FROM ACCOUNT WHERE ACCOUNT_ID = ? 
เวลาเรา exec command ก้อจะเห็นว่ารูปแบบ sql ไม่เปลี่ยน ครับ 
db engine จะไม่ทำการ compile sql ใหม่ครับและจะนำส่วนที่ catch เก็บไว้มาใช้ครับ

แต่ถ้าเรา query แบบนี้ 
SELECT * FROM ACCOUNT WHERE ACCOUNT_ID = '00001';
SELECT * FROM ACCOUNT WHERE ACCOUNT_ID = '00002';
db engine จะมองว่า sql มีการเปลี่ยนแปลงครับก้อจะทำ compile sql ใหม่ทุกครั้งครับ
ที่มีการ query ครับ 



#Example VB6
การ Insert โดยใช้ Query แบบปกติ
'--------------------------------------------------------------------------------------------------
Private  Sub XXX()
For i = 1 To 100000
        Call IntestDatal(i)        
    Next 
End Sub

Private Sub IntestDatal(ByVal pdata As Long)
Dim SQL As String
Dim lard As ADODB.Recordset
On Error GoTo LineError
    SQL = "INSERT INTO Persons(LASTNAME,FIRSTNAME) "
    SQL = SQL & " VALUES('Jim" & pdata & "','R." & pdata & "') "
    Me.MousePointer = vbHourglass
    Set lard = Nothing
    Set lard = clsDBConnect.Connection.Execute(SQL)
   Me.MousePointer = vbDefault
LineExit:
    Exit Sub
LineError:
    MsgBox Err.Number & ":" & Err.Description & vbNewLine & "in " & Err.Source, vbInformation + vbOKOnly
    Me.MousePointer = vbDefault
End Sub


การ Insert โดยใช้  prepare statements
'----------------------------------------------------------------------------------------------------
Private  Sub XXX()
For i = 1 To 100000
        Call CreatePrepareConnection()
        Call IntestDatal(i)        
    Next 
End Sub

Private Sub IntestDatal(ByVal pdata As Long)
On Error GoTo LineError
    Me.MousePointer = vbHourglass
    'pass the values that need to be inserted to specific parameters that we created above
    cmdSQLInsert("LASTNAME") = "XX" & pdata
    cmdSQLInsert("FIRSTNAME") = "YY" & pdata
    'Execute the command
    cmdSQLInsert.Execute
    Me.MousePointer = vbDefault
LineExit:
    Exit Sub
LineError:
    MsgBox Err.Number & ":" & Err.Description & vbNewLine & "in " & Err.Source, vbInformation + vbOKOnly
    Me.MousePointer = vbDefault
End Sub



Private Sub CreatePrepareConnection()
On Error GoTo LineError
 Set cmdSQLInsert = New ADODB.Command
    'Create the query
    cmdSQLInsert.CommandText = "Insert Into Persons(LASTNAME,FIRSTNAME) Values(?,?)"
    cmdSQLInsert.CommandType = adCmdText
    cmdSQLInsert.Prepared = True
    
    'Create the parameters
    'in this case we will create three parameters
    '-----Param 1 (for Field LASTNAME)-------------
    Dim gParam As ADODB.Parameter
    Set gParam = New ADODB.Parameter
    With gParam
        .Name = "LASTNAME"
        .Direction = adParamInput
        .Type = adVarChar
        .Size = 50
        .Value = "x"
    End With
    cmdSQLInsert.Parameters.Append gParam
    
    '-----Param 2 (for Field Name)-------------
    Set gParam = Nothing
    Set gParam = New ADODB.Parameter
    With gParam
        .Name = "FIRSTNAME"
        .Direction = adParamInput
        .Type = adVarChar
        .Size = 50
        .Value = "l"
    End With
    cmdSQLInsert.Parameters.Append gParam
    
    'Set the connection property of the command object
    Set cmdSQLInsert.ActiveConnection = clsDBConnect.Connection
LineExit:
    Exit Sub
LineError:
    MsgBox Err.Number & ":" & Err.Description & vbNewLine & "in " & Err.Source, vbInformation + vbOKOnly
    Me.MousePointer = vbDefault
End Sub