วิธีทำ มีมากกว่าหนึ่งวิธีค่ะ ขอใช้วิธีที่ตัวเองถนัดที่สุดนะคะ
ชื่อ table กับชื่อ field ไปเปลี่ยนเอานะคะ
ซึ่งเข้าใจว่า วันสั่ง กับ วันส่งของ จะอยู่ table เดียวกัน
และน่าจะเป็น MSSQL Server
ใช้ SQL COMMAND แบบ SUB QUERY เพื่อ EXECUTESCALAR ออกมาครั้งเดียว
Code (VB.NET)
SELECT
CASE TOTALRECORD
WHEN 0 THEN 0
ELSE TOTALSHIPMENTDAY / TOTALRECORD
END AS DILIVERY_MEAN_TIME
FROM
(
SELECT ISNULL(SUM(DATEDIFF(DAY ,[ORDERDATE],[SHIPDATE])),0) AS TOTALSHIPMENTDAY
,COUNT(PurchaseOrderID) AS TOTALRECORD
FROM Purchasing.PurchaseOrderHeader
WHERE ORDERDATE BETWEEN @DATESTART AND @DATEEND
) AS PRIMARYQUERY
'คำอธิบาย
' a. ที่ใช้ CASE ใน main select เพราะ ในกรณีที่ไม่มีข้อมูล ค่าของ TOTALRECORD จะเป็น 0
' ซึ่งจะ RUN ไม่ผ่านเพราะ ERROR DIVIDE BY ZERO ค่ะ
' b. ISNULL() เหตุผลเช่นดียวกันค่ะ
' c. ORDERDATE ชื่อ field ของวันที่ สั่งสินค้า
' d. SHIPDATE ชื่อ field ของวันที่ ส่งสินค้า
' e. PurchaseOrderID ชื่อ field ของ Primary key ในตารางนี้เพื่อหาจำนวน record
' f. Purchasing.PurchaseOrderHeader ชื่อ table
' g. ในส่วน where ของ Sub query ใช้ Parameter 2 ตัว @DATESTART และ @DATEEND
' โดยยยึดเอาวัน สั่งสินค้าเป็นหลัก ค่ะ การใช้ PARAMETER ในการเรียกข้อมูล
' ลองดูตัวอย่างใน กระทู้อื่นๆดูนะคะ ที่ต้องใช้ก้อเพื่อป้องกัน การ ERROR ของการ SET DATE FORMAT ค่ะ
' ด้วยการผ่านแบบ parameter จะมั่นใจได้ว่าข้อมูลถูกต้องและ run ได้ทุกเครื่องค่ะ
' h. ใน subquery จะเป็นการเตรียมข้อมูลจาก requirement ในข้อ 1. 2. 3. 4. ก่อน
' จากนั้น main query จะตรวจเงื่อนไขในข้อ a เพื่อคำนวนผลลัพธ์สุดท้ายค่ะ
'ข้อ c d e f เปลี่ยนเป็นชื่อ ที่ใช้ในฐานข้อมูลค่ะ
Date :
2010-02-14 01:15:44
By :
blurEye
No. 4
Guest
Dim strDay3Month = 15 / 1 / 2001
Dim strdayend = 17 / 1 / 2001
sql = "SELECT" & _
" Case TOTALRECORD " & _
" WHEN 0 THEN 0 " & _
" ELSE(TOTALSHIPMENTDAY / TOTALRECORD) " & _
" END AS DILIVERY_MEAN_TIME FROM " & _
"( SELECT ISNULL(SUM(DATEDIFF(DAY ,[RequestDate],[DeliveryDate])),0) AS TOTALSHIPMENTDAY ,COUNT(OrderLineID) AS TOTALRECORD " & _
" FROM(MOR_PO_Detail) " & _
" WHERE MOR_PO_Detail.RequestDate BETWEEN '" & strDay3Month & "' and '" & strdayend & "') AS PRIMARYQUERY "
cmd = New SqlCommand(sql, MConn)
' cmd.Parameters.Add("@DATESTART", SqlDbType.NVarChar).Value = 15 / 1 / 2001
' cmd.Parameters.Add("@DATEEND", SqlDbType.NVarChar).Value = 17 / 1 / 2001
MConn.Open()
cmd.ExecuteNonQuery()
MConn.Close()
เขียนอย่างนี้ไว้ค่ะ มันฟ้องว่า Line 1: Incorrect syntax near ')'.
คือตอนแรกก็ใช้ @D... แต่ว่าไม่แน่ใจว่าใช้ถูกหรือป่าว
อย่างนี้ต้องทำอย่างไรหรอคะ
Server Error in '/' Application.
Line 1: Incorrect syntax near ')'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: Line 1: Incorrect syntax near ')'.
Source Error:
Line 48: cmd.Parameters.Add("@DATEEND", SqlDbType.NVarChar).Value = strdayend
Line 49: MConn.Open()
Line 50: cmd.ExecuteNonQuery()
Line 51: MConn.Close()
Line 52: End Sub
'ทดลอง ทำเป็น console application run ผ่าน ผลลัพธ์ถูกต้องค่ะ
'Error ของคุณเกิดจาก FROM (MOR_PO_Detail)
'เอาวงเล็บออกค่ะ >> FROM MOR_PO_Detail
Imports System.Data.SqlClient
Imports System.Text
Module Module1
Sub Main()
System.Console.WriteLine(GetDiliveryMeanTime(DateSerial(2001, 1, 1), System.DateTime.Now).ToString())
System.Console.ReadLine()
End Sub
Public Function GetDiliveryMeanTime(ByVal StartDate As Date, ByVal EndDate As Date) As Double
Dim SQlConnectionString As String = "Data Source=GARFIELDS\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True"
Dim SQLCommandStr As String
Dim resultRate As Double = 0
'stringbuilder for well sql command pattern
Dim myString As StringBuilder = New StringBuilder()
myString.AppendLine(" SELECT ")
myString.AppendLine(" CASE TOTAL_RECORD ")
myString.AppendLine(" WHEN 0 THEN 0")
myString.AppendLine(" ELSE (TOTAL_SHIPMENT_DAY/TOTAL_RECORD)")
myString.AppendLine(" END AS DILIVERY_MEAN_TIME")
myString.AppendLine(" FROM ")
myString.AppendLine(" (")
myString.AppendLine(" Select ISNULL(SUM(DateDiff(Day, [ORDERDATE], [SHIPDATE])), 0) AS TOTAL_SHIPMENT_DAY")
myString.AppendLine(" ,COUNT([PurchaseOrderID]) AS TOTAL_RECORD")
myString.AppendLine(" FROM Purchasing.PurchaseOrderHeader ")
myString.AppendLine(" WHERE ORDERDATE BETWEEN @DATE_START AND @DATE_END")
myString.AppendLine(" ) AS PRIMARYQUERY ;")
SQLCommandStr = myString.ToString()
Dim MyConn As SqlConnection = New SqlConnection(SQlConnectionString)
Dim MyCommand = New SqlCommand(SQLCommandStr, MyConn)
MyCommand.Parameters.AddWithValue("@DATE_START", StartDate)
MyCommand.Parameters.AddWithValue("@DATE_END", EndDate)
Try
MyConn.Open()
resultRate = System.Convert.ToDouble(MyCommand.ExecuteScalar())
Catch ex As Exception
resultRate = -1
Throw New Exception(ex.Message)
Finally
If Not (MyConn Is Nothing) Then MyConn.Close()
End Try
Return resultRate
End Function
End Module
มันฟ้องอย่างนี้ค่ะ
Line 1: Incorrect syntax near ')'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: Line 1: Incorrect syntax near ')'.
Source Error:
Line 48: myString.AppendLine(" ) AS PRIMARYQUERY ;")
Line 49:
Line 50: SQLCommandStr = myString.ToString()
Line 51: Dim MyConn As SqlConnection = New SqlConnection(SQlConnectionString)
Line 52: Dim MyCommand = New SqlCommand(SQLCommandStr, MyConn)
เขียนไว้แบบนี้ค่ะ
ublic Function GetDiliveryMeanTime(ByVal StartDate As Date, ByVal EndDate As Date) As Double
Dim SQlConnectionString As String = WebConfigurationManager.ConnectionStrings("MORConnect").ToString()
Dim SQLCommandStr As String
Dim resultRate As Double = 0
'stringbuilder for well sql command pattern
Dim myString As StringBuilder = New StringBuilder()
myString.AppendLine(" SELECT ")
myString.AppendLine(" CASE TOTAL_RECORD ")
myString.AppendLine(" WHEN 0 THEN 0")
myString.AppendLine(" ELSE (TOTAL_SHIPMENT_DAY/TOTAL_RECORD)")
myString.AppendLine(" END AS DILIVERY_MEAN_TIME")
myString.AppendLine(" FROM ")
myString.AppendLine(" (")
myString.AppendLine(" Select ISNULL(SUM(DateDiff(Day, [RequestDate],[DeliveryDate)), 0) AS TOTAL_SHIPMENT_DAY")
myString.AppendLine(" ,COUNT([OrderLineID]) AS TOTAL_RECORD")
myString.AppendLine(" FROM MOR_PO_Detail ")
myString.AppendLine(" WHERE RequestDate BETWEEN @DATE_START AND @DATE_END")
myString.AppendLine(" ) AS PRIMARYQUERY ;")
SQLCommandStr = myString.ToString()
Dim MyConn As SqlConnection = New SqlConnection(SQlConnectionString)
Dim MyCommand = New SqlCommand(SQLCommandStr, MyConn)
MyCommand.Parameters.AddWithValue("@DATE_START", StartDate)
MyCommand.Parameters.AddWithValue("@DATE_END", EndDate)
Try
MyConn.Open()
resultRate = System.Convert.ToDouble(MyCommand.ExecuteScalar())
Catch ex As Exception
resultRate = -1
Throw (New Exception(ex.Message))
Finally
If Not (MyConn Is Nothing) Then MyConn.Close()
End Try
อ่อค่ะ
แต่มีปัญหาอีกแล้วค่ะ คือจะเช็คค่าวันที่ ให้มากกว่าหรือเท่ากับวันที่ปัจจุบัน
พอดีเขียน sql ไว้อย่างนี้ค่ะ
SELECT SUM(QTYorder) AS qty, ID AS IDNo
FROM dbo.Test1
WHERE (ETAWHH >= { fn NOW() })
GROUP BY ID
เอาเรื่องเดิมก่อน
แยกไว้ใน Class ที่สร้างขึ้นได้เลยค่ะ
Arithmetic overflow error converting expression to data type int.
ไม่น่าจะมีนะคะ ตรวจสอบให้ดีเพราะใช้ Double ไม่มี int เลย
Code (VB.NET)
Imports System.Data.SqlClient
Imports System.Text
Public Class DatabaseSpecial
Public Shared SQlConnectionString As String = "Data Source=GARFIELDS\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True"
Public Shared Function GetDiliveryMeanTime(ByVal StartDate As Date, ByVal EndDate As Date) As Double
Dim SQLCommandStr As String
Dim resultRate As Double = 0
'stringbuilder for well sql command pattern
Dim myString As StringBuilder = New StringBuilder()
myString.AppendLine(" SELECT ")
myString.AppendLine(" CASE TOTAL_RECORD ")
myString.AppendLine(" WHEN 0 THEN 0")
myString.AppendLine(" ELSE (TOTAL_SHIPMENT_DAY/TOTAL_RECORD)")
myString.AppendLine(" END AS DILIVERY_MEAN_TIME")
myString.AppendLine(" FROM ")
myString.AppendLine(" (")
myString.AppendLine(" Select ISNULL(SUM(DateDiff(Day, [ORDERDATE], [SHIPDATE])), 0) AS TOTAL_SHIPMENT_DAY")
myString.AppendLine(" ,COUNT([PurchaseOrderID]) AS TOTAL_RECORD")
myString.AppendLine(" FROM Purchasing.PurchaseOrderHeader ")
myString.AppendLine(" WHERE ORDERDATE BETWEEN @DATE_START AND @DATE_END")
myString.AppendLine(" ) AS PRIMARYQUERY ;")
SQLCommandStr = myString.ToString()
Dim MyConn As SqlConnection = New SqlConnection(SQlConnectionString)
Dim MyCommand = New SqlCommand(SQLCommandStr, MyConn)
MyCommand.Parameters.AddWithValue("@DATE_START", StartDate)
MyCommand.Parameters.AddWithValue("@DATE_END", EndDate)
Try
MyConn.Open()
resultRate = System.Convert.ToDouble(MyCommand.ExecuteScalar())
Catch ex As Exception
resultRate = -1
Throw New Exception(ex.Message)
Finally
If Not (MyConn Is Nothing) Then MyConn.Close()
End Try
Return resultRate
End Function
End Class
ตัวอย่างการเรียกค่ะ Code (VB.NET)
Sub Main()
System.Console.WriteLine(DatabaseSpecial.GetDiliveryMeanTime(DateSerial(2001, 1, 1), System.DateTime.Now).ToString())
System.Console.ReadLine()
End Sub
Dim ExactlyDate as DateTime = DateSerial( DateTime.Now.year ,DateTime.Now.Month
,DateTime.Now.Day) // เวลาจะเป็น ศูนย์นาฬิกาของวันนี้ ก้อเอาตัสแปรนี้ไปแทนอะค่ะ
' ค่าที่ได้ 2010-02-14 00:00:00.000
' หรือ ที่ Where clause แก้เป็นแบบนี้จะได้ผลลัพธ์เดียวกัน
WHERE DeliveryDate >= DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
รันผ่าน tool ของ SQL SERVER ดูแล้วจะได้ค่าแบบนี้
ปล. Code (VB.NET)
Dim StartDate As DateTime = DateSerial(2001, 1, 1)
Dim EndsDate As DateTime = System.DateTime.Now
Dim DMeantTime As Double= DatabaseSpecial.GetDiliveryMeanTime( StartDate ,EndsDate )
'จะเข้าใจง่ายกว่าปะคะ
Dim StartDate As DateTime = DateSerial(2001, 1, 1)
Dim EndsDate As DateTime = System.DateTime.Now
Dim DMeantTime As Double= DatabaseSpecial.GetDiliveryMeanTime( StartDate ,EndsDate )
'จะเข้าใจง่ายกว่าปะคะ