มีบทความมากมายเกี่ยวกับ ASP และ Stored Procedures (Stored Procedures) แต่ฉันสงสัยว่าผู้เขียนได้ฝึกฝนจริงหรือไม่ ตอนที่ฉันยังเป็นมือใหม่ ฉันศึกษาข้อมูลที่เกี่ยวข้องมากมายและพบว่าวิธีการหลายวิธีที่ให้มานั้นไม่เหมือนกันในทางปฏิบัติ สำหรับการใช้งานแบบง่าย สื่อเหล่านี้อาจมีประโยชน์ แต่จำกัดอยู่เพียงเท่านี้ เนื่องจากโดยพื้นฐานแล้วจะเหมือนกันและคัดลอกซึ่งกันและกัน สำหรับการใช้งานที่ซับซ้อนกว่าเล็กน้อย จึงไม่ชัดเจนทั้งหมด
ตอนนี้ฉันเข้าถึง SQL Server โดยการเรียกขั้นตอนการจัดเก็บ แม้ว่าข้อความต่อไปนี้ไม่สามารถรับประกันได้ว่าถูกต้องอย่างแน่นอน แต่ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน
โพรซีเดอร์ที่เก็บไว้คือคำสั่ง SQL หนึ่งคำสั่งขึ้นไปที่จัดเก็บไว้ในฐานข้อมูลเป็นออบเจ็กต์ที่ปฏิบัติการได้
คำจำกัดความนั้นเป็นนามธรรมเสมอ จริงๆ แล้ว Stored Procedure คือชุดของคำสั่ง SQL ที่สามารถดำเนินการบางอย่างให้เสร็จสิ้นได้ แต่ชุดคำสั่งนี้จะอยู่ในฐานข้อมูล (ในที่นี้เราจะพูดถึง SQL Server เท่านั้น) หากเราสร้าง Stored Procedure และเรียก Stored Procedure ใน ASP เราสามารถหลีกเลี่ยงการผสมคำสั่ง SQL กับโค้ด ASP ได้ มีประโยชน์อย่างน้อยสามประการในการทำเช่นนี้:
ประการแรก ปรับปรุงประสิทธิภาพอย่างมาก ความเร็วการดำเนินการของ Stored Procedure นั้นเร็วมาก และการเรียก Stored Procedure สามารถลดจำนวนการโต้ตอบกับฐานข้อมูลได้อย่างมาก
ประการที่สอง ปรับปรุงความปลอดภัย หากคุณผสมคำสั่ง SQL ในโค้ด ASP เมื่อโค้ดถูกโจมตี นั่นหมายความว่าโครงสร้างไลบรารีถูกโจมตีด้วย
ประการที่สาม เอื้อต่อการนำคำสั่ง SQL มาใช้ซ้ำ
ใน ASP โดยทั่วไปจะเรียกกระบวนงานที่เก็บไว้ผ่านวัตถุคำสั่ง ทั้งนี้ขึ้นอยู่กับสถานการณ์ บทความนี้ยังแนะนำวิธีการเรียกอื่นๆ เพื่อความสะดวกในการอธิบาย การจำแนกประเภทง่ายๆ ต่อไปนี้จัดทำขึ้นตามอินพุตและเอาต์พุตของกระบวนการที่เก็บไว้:
1. ขั้นตอนการจัดเก็บที่ส่งคืนชุดระเบียนเดียวเท่านั้น
สมมติว่ามี Stored Procedure ต่อไปนี้ (จุดประสงค์ของบทความนี้ไม่ได้เพื่ออธิบายไวยากรณ์ T-SQL ดังนั้น Stored Procedure จะให้โค้ดโดยไม่มีคำอธิบายเท่านั้น):
/*SP1*/
สร้างขั้นตอน dbo.getUserList
เช่น
ตั้งค่า nocount บน
เริ่ม
เลือก * จาก dbo [ข้อมูลผู้ใช้]
จบ
ไป
รับระเบียนทั้งหมดในตาราง userinfo และส่งกลับชุดระเบียน รหัส ASP สำหรับการเรียกกระบวนงานที่เก็บไว้ผ่านวัตถุคำสั่งมีดังนี้:
'**การเรียกกระบวนงานที่เก็บไว้ผ่านวัตถุคำสั่ง**
DIM MyComm, MyRst
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
MyComm.CommandText = "getUserList" 'ระบุชื่อกระบวนงานที่เก็บไว้
MyComm.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
MyComm.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
ตั้งค่า MyRst = MyComm.Execute
Set MyComm = Nothing
ชุดบันทึกที่ได้รับจากขั้นตอนการจัดเก็บถูกกำหนดให้กับ MyRst จากนั้น MyRst ก็สามารถดำเนินการได้
ในโค้ดข้างต้น แอตทริบิวต์ CommandType ระบุประเภทของคำขอ ค่าและคำอธิบายมีดังนี้:
-1 บ่งชี้ว่าไม่สามารถกำหนดประเภทของพารามิเตอร์ CommandText ได้
1 ระบุว่า CommandText เป็นประเภทคำสั่งทั่วไป
2 บ่งชี้ว่าพารามิเตอร์ CommandText เป็นชื่อตารางที่มีอยู่
4 ระบุว่าพารามิเตอร์ CommandText เป็นชื่อของขั้นตอนที่เก็บไว้
นอกจากนี้ยังสามารถเรียกขั้นตอนที่เก็บไว้ผ่านวัตถุการเชื่อมต่อหรือวัตถุชุดระเบียนได้ดังนี้:
'**เรียกขั้นตอนที่เก็บไว้ผ่านวัตถุการเชื่อมต่อ**
DIM MyConn, MyRst
ตั้งค่า MyConn = Server.CreateObject("ADODB.Connection")
MyConn.open MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
Set MyRst = MyConn.Execute("getUserList",0,4) 'พารามิเตอร์สุดท้ายมีความหมายเหมือนกับ CommandType
Set MyConn = Nothing
'**เรียกกระบวนงานที่เก็บไว้ผ่านวัตถุ Recordset**
ติ่มซำ MyRst
ตั้งค่า MyRst = Server.CreateObject("ADODB.Recordset")
MyRst.open "getUserList",MyConStr,0,1,4
'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล พารามิเตอร์สุดท้ายมีความหมายเหมือนกับ CommandType
2. ขั้นตอนการจัดเก็บโดยไม่มีอินพุตและเอาต์พุต
โปรดดูขั้นตอนการจัดเก็บต่อไปนี้:
/*SP2*/
สร้างขั้นตอน dbo.delUserAll
เช่น
ตั้งค่า nocount บน
เริ่ม
ลบออกจาก dbo [ข้อมูลผู้ใช้]
จบ
go
จะลบบันทึกทั้งหมดในตาราง userinfo โดยไม่มีอินพุตหรือเอาต์พุตใด ๆ โดยพื้นฐานแล้ววิธีการเรียกจะเหมือนกับที่กล่าวไว้ข้างต้น ยกเว้นว่าไม่จำเป็นต้องได้รับชุดบันทึก:
'**เรียกใช้ขั้นตอนที่เก็บไว้ผ่านคำสั่ง วัตถุ**
ติ่มซำ MyComm
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
MyComm.CommandText = "delUserAll" 'ระบุชื่อกระบวนงานที่เก็บไว้
MyComm.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
MyComm.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
MyComm.Execute 'ไม่จำเป็นต้องได้รับชุดบันทึกที่นี่
Set MyComm = Nothing
แน่นอนว่า Stored Procedure ดังกล่าวยังสามารถเรียกผ่านวัตถุ Connection หรือ Recordset ได้ แต่วัตถุ Recordset จะถูกสร้างขึ้นเพื่อรับชุดระเบียน ถ้าไม่มีการส่งคืนชุดระเบียน จะเป็นการดีกว่าถ้าใช้วัตถุ Command
3. ขั้นตอนการจัดเก็บพร้อมค่าส่งคืน
เมื่อดำเนินการเหมือน SP2 คุณควรใช้ความสามารถในการประมวลผลธุรกรรมที่มีประสิทธิภาพของ SQL Server อย่างเต็มที่เพื่อรักษาความสอดคล้องของข้อมูล นอกจากนี้ เราอาจจำเป็นต้องมีขั้นตอนการจัดเก็บเพื่อคืนสถานะการดำเนินการ ด้วยเหตุนี้ ให้แก้ไข SP2 ดังนี้:
/*SP3*/
สร้างขั้นตอน dbo.delUserAll
เช่น
ตั้งค่า nocount บน
เริ่ม
เริ่มต้นการทำธุรกรรม
ลบออกจาก dbo [ข้อมูลผู้ใช้]
หาก @@ข้อผิดพลาด=0
เริ่ม
กระทำธุรกรรม
กลับ 1
จบ
อื่น
เริ่ม
ธุรกรรมย้อนกลับ
กลับ 0
จบ
กลับ
จบ
จะส่ง
คืนค่า 1 เมื่อดำเนินการลบสำเร็จ มิฉะนั้นจะส่งคืนค่า 0 และดำเนินการย้อนกลับ ในการรับค่าที่ส่งคืนใน ASP คุณต้องใช้คอลเลกชันพารามิเตอร์เพื่อประกาศพารามิเตอร์:
'**เรียกกระบวนงานที่เก็บไว้ด้วยค่าที่ส่งคืนและรับค่าที่ส่งคืน**
ติ่มซำ MyComm, MyPara
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
MyComm.CommandText = "delUserAll" 'ระบุชื่อกระบวนงานที่เก็บไว้
MyComm.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
MyComm.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
'ประกาศค่าส่งคืน
ตั้งค่า Mypara = MyComm.CreateParameter("RETURN",2,4)
MyComm.Parameters.Append MyPara
MyComm.Execute
'รับค่าส่งคืน
DIM retValue
retValue = MyComm(0) 'หรือ retValue = MyComm.Parameters(0)
ตั้งค่า MyComm = Nothing
In MyComm.CreateParameter("RETURN",2,4) ความหมายของแต่ละพารามิเตอร์จะเป็นดังนี้:
พารามิเตอร์แรก ("RETURE") คือชื่อพารามิเตอร์ ชื่อพารามิเตอร์สามารถตั้งค่าได้ตามใจชอบ แต่โดยทั่วไปควรเหมือนกับชื่อพารามิเตอร์ที่ประกาศในขั้นตอนการจัดเก็บ นี่คือค่าที่ส่งคืน ฉันมักจะตั้งค่าเป็น "RETURE"
พารามิเตอร์ตัวที่สอง (2) ระบุประเภทข้อมูลของพารามิเตอร์ โปรดดูรหัสประเภททั่วไปตามการอ้างอิง ADO:
โฆษณาใหญ่: 20;
ไบนารี่เสริม: 128;
แอดบูลีน: 11;
โฆษณาชาร์: 129;
addDBTimeStamp: 135;
โฆษณาว่าง: 0;
จำนวนเต็มโฆษณา: 3;
โฆษณาขนาดเล็กInt: 2;
adTinyInt: 16;
โฆษณาวาร์ชาร์: 200;
สำหรับค่าตอบแทนสามารถรับได้เฉพาะค่าจำนวนเต็มและ -1 ถึง -99 เป็นค่าที่สงวนไว้
พารามิเตอร์ตัวที่สาม (4) ระบุถึงลักษณะของพารามิเตอร์ โดยที่ 4 ระบุว่านี่คือค่าที่ส่งคืน คำอธิบายของค่าของพารามิเตอร์นี้มีดังนี้:
0: ไม่สามารถระบุประเภทได้ 1: พารามิเตอร์อินพุต 2: พารามิเตอร์อินพุตหรือเอาท์พุต 4: ค่าส่งคืน
รหัส ASP ที่ให้ไว้ข้างต้นควรเป็นโค้ดที่สมบูรณ์นั่นคือโค้ดที่ซับซ้อนที่สุด ที่จริงแล้ว
ให้ตั้งค่า Mypara = MyComm.CreateParameter("RETURN",2,
MyComm.Parameters.Append MyPara
สามารถทำให้ง่ายขึ้นเป็น
MyComm.Parameters.Append MyComm.CreateParameter("RETURN",2,4)
และยังสามารถทำให้ง่ายขึ้นต่อไปได้ ซึ่งจะอธิบายในภายหลัง
สำหรับกระบวนงานที่เก็บไว้พร้อมพารามิเตอร์สามารถเรียกได้โดยใช้วัตถุ Command เท่านั้น (ยังมีข้อมูลที่สามารถเรียกผ่านวัตถุ Connection หรือวัตถุ Recordset ได้ แต่ฉันยังไม่ได้ลอง)
4. ขั้นตอนการจัดเก็บพร้อมพารามิเตอร์อินพุตและพารามิเตอร์เอาต์พุต
ค่าที่ส่งคืนคือพารามิเตอร์เอาต์พุตพิเศษจริงๆ ในกรณีส่วนใหญ่ เราใช้ขั้นตอนการจัดเก็บที่มีทั้งพารามิเตอร์อินพุตและเอาต์พุต ตัวอย่างเช่น เราต้องการรับชื่อผู้ใช้ที่มี ID ที่แน่นอนในตารางข้อมูลผู้ใช้ ในขณะนี้ มีพารามิเตอร์อินพุต --user ID และพารามิเตอร์เอาต์พุต----ชื่อผู้ใช้ ขั้นตอนการจัดเก็บเพื่อใช้ฟังก์ชันนี้มีดังนี้:
/*SP4*/
สร้างขั้นตอน dbo.getUserName
@UserID อินท์
@ชื่อผู้ใช้ varchar (40) เอาต์พุต
เช่น
ตั้งค่า nocount บน
เริ่ม
หาก @UserID เป็นค่าว่างส่งคืน
เลือก @UserName=ชื่อผู้ใช้
จาก dbo.[ข้อมูลผู้ใช้]
โดยที่ userid=@UserID
กลับ
จบ
การ
เรียกขั้นตอนที่เก็บไว้มีดังนี้:
'**เรียกขั้นตอนที่เก็บไว้ด้วยพารามิเตอร์อินพุตและเอาต์พุต**
DIM MyComm, ID ผู้ใช้, ชื่อผู้ใช้
รหัสผู้ใช้ = 1
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
MyComm.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
MyComm.CommandText = "getUserName" 'ระบุชื่อกระบวนงานที่เก็บไว้
MyComm.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
MyComm.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
'ประกาศพารามิเตอร์'
MyComm.Parameters.append MyComm.CreateParameter("@UserID",3,1,4,UserID)
MyComm.Parameters.append MyComm.CreateParameter("@UserName",200,2,40)
MyComm.Execute
'รับพารามิเตอร์'
ชื่อผู้ใช้ = MyComm(1)
Set MyComm = Nothing
ในโค้ดข้างต้น คุณจะเห็นว่าต่างจากการประกาศค่าส่งคืน โดยต้องใช้พารามิเตอร์ 5 ตัวเมื่อประกาศพารามิเตอร์อินพุต และต้องใช้พารามิเตอร์ 4 ตัวเมื่อประกาศพารามิเตอร์เอาต์พุต เมื่อประกาศพารามิเตอร์อินพุต พารามิเตอร์ทั้งห้าได้แก่: ชื่อพารามิเตอร์ ประเภทข้อมูลพารามิเตอร์ ประเภทพารามิเตอร์ ความยาวข้อมูล และค่าพารามิเตอร์ เมื่อประกาศพารามิเตอร์เอาต์พุต จะไม่มีพารามิเตอร์สุดท้าย: ค่าพารามิเตอร์
ควรให้ความสนใจเป็นพิเศษ: เมื่อประกาศพารามิเตอร์ ลำดับจะต้องเหมือนกับลำดับที่กำหนดไว้ในขั้นตอนการจัดเก็บ และประเภทข้อมูลและความยาวของแต่ละพารามิเตอร์จะต้องเหมือนกันกับที่กำหนดไว้ในขั้นตอนการจัดเก็บด้วย
หากขั้นตอนการจัดเก็บมีหลายพารามิเตอร์ รหัส ASP จะดูยุ่งยาก คุณสามารถใช้คำสั่ง with เพื่อลดความซับซ้อนของรหัส:
'**เรียกขั้นตอนการจัดเก็บด้วยพารามิเตอร์อินพุตและเอาต์พุต (รหัสแบบง่าย)**
DIM MyComm, ID ผู้ใช้, ชื่อผู้ใช้
รหัสผู้ใช้ = 1
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
กับMyComm
.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
.CommandText = "getUserName" 'ระบุชื่อกระบวนงานที่เก็บไว้
.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
.Parameters.append .CreateParameter("@UserID",3,1,4,UserID)
.Parameters.append .CreateParameter("@ชื่อผู้ใช้",200,2,40)
.ดำเนินการ
ลงท้ายด้วย
ชื่อผู้ใช้ = MyComm(1)
Set MyComm = Nothing
หากเราต้องการรับชื่อผู้ใช้ 10 ผู้ใช้ที่มี ID 1 ถึง 10 เราจำเป็นต้องสร้าง Command object 10 ครั้งหรือไม่? เลขที่ หากคุณต้องการเรียกใช้โพรซีเดอร์ที่เก็บไว้เดียวกันหลายครั้ง เพียงเปลี่ยนพารามิเตอร์อินพุตแล้วคุณจะได้ผลลัพธ์ที่แตกต่างกัน:
'**การเรียกโพรซีเดอร์ที่เก็บไว้เดียวกันหลายครั้ง**
DIM MyComm, ID ผู้ใช้, ชื่อผู้ใช้
ชื่อผู้ใช้ = ""
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
สำหรับ UserID = 1 ถึง 10
กับMyComm
.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
.CommandText = "getUserName" 'ระบุชื่อกระบวนงานที่เก็บไว้
.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
ถ้า UserID = 1 แล้ว
.Parameters.append .CreateParameter("@UserID",3,1,4,UserID)
.Parameters.append .CreateParameter("@ชื่อผู้ใช้",200,2,40)
.ดำเนินการ
อื่น
'กำหนดค่าให้กับพารามิเตอร์อินพุตใหม่ (พารามิเตอร์อินพุตและพารามิเตอร์เอาต์พุตซึ่งค่าพารามิเตอร์ไม่เปลี่ยนแปลงในขณะนี้ไม่จำเป็นต้องประกาศอีกครั้ง)
.Parameters("@UserID") = UserID
.ดำเนินการ
สิ้นสุดถ้า
ลงท้ายด้วย
ชื่อผู้ใช้ = ชื่อผู้ใช้ + MyComm(1) + "," 'บางทีคุณอาจต้องการใช้ที่เก็บข้อมูลอาร์เรย์
ต่อไป
ตั้งค่า MyComm = ไม่มีสิ่งใด
ดังที่เห็นได้จากโค้ดด้านบน: เมื่อเรียกใช้โพรซีเดอร์ที่เก็บไว้เดียวกันซ้ำ ๆ คุณจะต้องกำหนดพารามิเตอร์อินพุตใหม่ซึ่งมีค่าที่เปลี่ยนแปลงไป วิธีนี้มีพารามิเตอร์อินพุตและเอาต์พุตหลายตัวและมีเพียงตัวเดียวเท่านั้นที่ถูกเรียก ในแต่ละครั้ง จำนวนโค้ดสามารถลดลงอย่างมากเมื่อค่าของพารามิเตอร์อินพุตเปลี่ยนแปลง
5. ขั้นตอนการจัดเก็บพร้อมค่าส่งคืน พารามิเตอร์อินพุต และพารามิเตอร์เอาต์พุตในเวลาเดียวกัน
ดังที่ได้กล่าวไว้ก่อนหน้านี้ เมื่อเรียกกระบวนงานที่เก็บไว้ ลำดับในการประกาศพารามิเตอร์จะต้องเหมือนกับลำดับที่กำหนดไว้ในกระบวนงานที่เก็บไว้ อีกประเด็นที่ควรให้ความสนใจเป็นพิเศษ: หากกระบวนงานที่เก็บไว้มีทั้งค่าที่ส่งคืนและพารามิเตอร์อินพุตและเอาต์พุต จะต้องประกาศค่าที่ส่งคืนก่อน
เพื่อสาธิตวิธีการเรียกในกรณีนี้ เรามาปรับปรุงตัวอย่างข้างต้นกัน ยังคงได้รับชื่อผู้ใช้ของผู้ใช้ที่มี ID 1 แต่อาจเป็นไปได้ว่าไม่มีผู้ใช้อยู่ (ผู้ใช้ถูกลบไปแล้ว และหมายเลขผู้ใช้เป็นฟิลด์ที่เพิ่มขึ้นเอง) ขั้นตอนการจัดเก็บส่งคืนค่าที่แตกต่างกันขึ้นอยู่กับว่ามีผู้ใช้อยู่หรือไม่ ในขณะนี้ ขั้นตอนการจัดเก็บและโค้ด ASP เป็นดังนี้:
/*SP5*/
สร้างขั้นตอน dbo.getUserName
--เพื่อที่จะให้ความรู้สึกถึง "คำสั่งซื้อ" ให้ลึกซึ้งยิ่งขึ้น ให้กลับลำดับคำจำกัดความของพารามิเตอร์สองตัวต่อไปนี้
@ชื่อผู้ใช้ varchar (40) เอาต์พุต
@ชื่อผู้ใช้ไอดี
เช่น
ตั้งค่า nocount บน
เริ่ม
หาก @UserID เป็นค่าว่างส่งคืน
เลือก @UserName=ชื่อผู้ใช้
จาก dbo.[ข้อมูลผู้ใช้]
โดยที่ userid=@UserID
ถ้า @@rowcount>0
กลับ 1
อื่น
กลับ 0
กลับ
จบ
ไป
'**เรียกโพรซีเดอร์ที่เก็บไว้พร้อมค่าส่งคืน พารามิเตอร์อินพุต และพารามิเตอร์เอาต์พุต**
DIM MyComm, ID ผู้ใช้, ชื่อผู้ใช้
รหัสผู้ใช้ = 1
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
กับMyComm
.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
.CommandText = "getUserName" 'ระบุชื่อกระบวนงานที่เก็บไว้
.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
'ต้องประกาศค่าที่ส่งคืนก่อน
.Parameters.Append .CreateParameter("RETURN",2,4)
'ลำดับการประกาศของพารามิเตอร์สองตัวต่อไปนี้จะกลับรายการตามลำดับเช่นกัน
.Parameters.append .CreateParameter("@ชื่อผู้ใช้",200,2,40)
.Parameters.append .CreateParameter("@UserID",3,1,4,UserID)
.ดำเนินการ
ลงท้ายด้วย
ถ้า MyComm(0) = 1 แล้ว
ชื่อผู้ใช้ = MyComm(1)
อื่น
ชื่อผู้ใช้ = "ไม่มีผู้ใช้รายนี้"
สิ้นสุดถ้า
ตั้งค่า MyComm = ไม่มีเลย
6. ขั้นตอนการจัดเก็บที่ส่งคืนพารามิเตอร์และชุดระเบียนในเวลาเดียวกัน
บางครั้ง เราจำเป็นต้องมีขั้นตอนการจัดเก็บเพื่อส่งคืนพารามิเตอร์และชุดบันทึกในเวลาเดียวกัน ตัวอย่างเช่น เมื่อใช้ขั้นตอนการจัดเก็บสำหรับเพจ เราจำเป็นต้องส่งคืนพารามิเตอร์ เช่น ชุดบันทึกและจำนวนข้อมูลทั้งหมดในเวลาเดียวกัน ต่อไปนี้เป็นขั้นตอนการจัดเก็บสำหรับการเพจ:
/*SP6*/
สร้างขั้นตอน dbo.getUserList
@iPageCount int OUTPUT, --จำนวนหน้าทั้งหมด
@iPage int, --หมายเลขหน้าปัจจุบัน
@iPageSize int --จำนวนบันทึกต่อหน้า
เช่น
ตั้งค่า nocount บน
เริ่ม
--สร้างตารางชั่วคราว
สร้างตาราง #t (ID int IDENTITY, --ฟิลด์เพิ่มอัตโนมัติ
รหัสผู้ใช้ int,
ชื่อผู้ใช้ varchar(40))
--เขียนข้อมูลลงในตารางชั่วคราว
ใส่เข้าไปใน #t
เลือก userid ชื่อผู้ใช้จาก dbo [UserInfo]
เรียงลำดับตามรหัสผู้ใช้
--รับจำนวนบันทึกทั้งหมด
ประกาศ @iRecordCount int
set @iRecordCount = @@rowcount
--กำหนดจำนวนหน้าทั้งหมด
หาก @iRecordCount%@iPageSize=0
SET @iPageCount=CEILING(@iRecordCount/@iPageSize)
อื่น
SET @iPageCount=CEILING(@iRecordCount/@iPageSize)+1
--หากหมายเลขหน้าที่ร้องขอมากกว่าจำนวนหน้าทั้งหมด หน้าสุดท้ายจะปรากฏขึ้น
หาก @iPage > @iPageCount
SELECT @iPage = @iPageCount
-- กำหนดจุดเริ่มต้นและจุดสิ้นสุดของหน้าปัจจุบัน
ประกาศ @iStart int --start บันทึก
ประกาศ @iEnd int --end บันทึก
เลือก @iStart = (@iPage - 1) * @iPageSize
SELECT @iEnd = @iStart + @iPageSize + 1
-- รับบันทึกหน้าปัจจุบัน
เลือก * จาก #t โดยที่ ID>@iStart และ ID<@iEnd
--ลบตารางชั่วคราว
DROP TABLE #t
--ส่งคืนจำนวนระเบียนทั้งหมด
กลับ @iRecordCount
จบ
ในขั้นตอนการจัดเก็บข้างต้น
ให้
ป้อนหมายเลขหน้าปัจจุบันและจำนวนบันทึกต่อหน้า และส่งกลับชุดบันทึกของหน้าปัจจุบัน จำนวนหน้าทั้งหมด และจำนวนบันทึกทั้งหมดเพื่อให้เป็นแบบทั่วไปมากขึ้น จำนวนระเบียนทั้งหมดจะถูกส่งกลับเป็นค่าที่ส่งคืน ต่อไปนี้เป็นรหัส ASP ที่เรียกขั้นตอนการจัดเก็บ (การดำเนินการเพจจิ้งเฉพาะจะถูกละเว้น):
'**เรียกขั้นตอนการจัดเก็บเพจจิ้ง**
DIM pagenow, ขนาดหน้า, จำนวนหน้า, จำนวนบันทึก
DIM MyComm, MyRst
pagenow = คำขอ ("pn")
'ฟังก์ชันแบบกำหนดเองที่ใช้ในการตรวจสอบจำนวนธรรมชาติ
ถ้า CheckNar(pagenow) = false ดังนั้น pagenow = 1
ขนาดหน้า = 20
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
กับMyComm
.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
.CommandText = "getUserList" 'ระบุชื่อขั้นตอนการจัดเก็บ
.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
'มูลค่าที่ส่งคืน (จำนวนบันทึกทั้งหมด)
.Parameters.Append .CreateParameter("RETURN",2,4)
'พารามิเตอร์เอาต์พุต (จำนวนหน้าทั้งหมด)
.Parameters.Append .CreateParameter("@iPageCount",3,2)
'พารามิเตอร์อินพุต (หมายเลขหน้าปัจจุบัน)
.Parameters.append .CreateParameter("@iPage",3,1,4,หน้าตอนนี้)
'พารามิเตอร์อินพุต (จำนวนบันทึกต่อหน้า)
.Parameters.append .CreateParameter("@iPageSize",3,1,4,ขนาดหน้า)
SetMyRst = .ดำเนินการ
ลงท้ายด้วย
ถ้า MyRst.state = 0 แสดงว่า 'ไม่ได้รับข้อมูล MyRst จะถูกปิด
จำนวนบันทึก = -1
อื่น
MyRst.close 'หมายเหตุ: หากต้องการรับค่าพารามิเตอร์ คุณต้องปิดวัตถุชุดระเบียนก่อน
จำนวนบันทึก = MyComm(0)
จำนวนหน้า = MyComm(1)
ถ้า cint(pagenow)>=cint(pagecount) ดังนั้น pagenow=pagecount
สิ้นสุดถ้า
ตั้งค่า MyComm = ไม่มี
'แสดงบันทึกด้านล่าง
ถ้าจำนวนบันทึก = 0 แล้ว
ตอบกลับเขียนว่า "ไม่มีบันทึก"
มิฉะนั้นถ้าจำนวนบันทึก> 0 แล้ว
MyRst.open
ทำจนถึง MyRst.EOF
-
วนซ้ำ
'ต่อไปนี้จะแสดงข้อมูลการแบ่งหน้า
-
อย่างอื่น 'recordcount=-1
การตอบสนองเขียน "ข้อผิดพลาดของพารามิเตอร์"
end ถ้า
เกี่ยวกับโค้ดข้างต้นมีเพียงจุดเดียวที่ต้องอธิบาย: เมื่อส่งคืนชุดระเบียนและพารามิเตอร์พร้อมกันหากคุณต้องการรับพารามิเตอร์คุณต้องปิดชุดระเบียนก่อนแล้วจึงเปิดเมื่อ โดยใช้ชุดระเบียน
7. ขั้นตอนการจัดเก็บที่ส่งคืนชุดระเบียนหลายชุด
สิ่งแรกที่บทความนี้แนะนำคือขั้นตอนการจัดเก็บที่ส่งกลับชุดระเบียน บางครั้ง จำเป็นต้องมีขั้นตอนการจัดเก็บเพื่อส่งคืนชุดระเบียนหลายชุด ใน ASP จะรับชุดระเบียนเหล่านี้พร้อมกันได้อย่างไร เพื่อที่จะอธิบายปัญหานี้ ให้เพิ่มสองฟิลด์ลงในตารางข้อมูลผู้ใช้: usertel และ usermail และตั้งค่าให้เฉพาะผู้ใช้ที่เข้าสู่ระบบเท่านั้นที่สามารถดูเนื้อหาทั้งสองนี้ได้
/*SP7*/
สร้างขั้นตอน dbo.getUserInfo
@userid อินท์
@checklogin บิต
เช่น
ตั้งค่า nocount บน
เริ่ม
ถ้า @userid เป็นโมฆะ หรือ @checklogin เป็นโมฆะ ให้ส่งคืน
เลือกชื่อผู้ใช้
จาก dbo.[usrinfo]
โดยที่ userid=@userid
--หากคุณเป็นผู้ใช้ที่เข้าสู่ระบบ ให้ใช้ usertel และ usermail
ถ้า @checklogin=1
เลือก usertel, usermail
จาก dbo.[ข้อมูลผู้ใช้]
โดยที่ userid=@userid
กลับ
จบ
ต่อไปนี้
เป็นรหัส ASP:
'**เรียกกระบวนงานเก็บไว้ที่ส่งกลับชุดระเบียนหลายชุด**
ตรวจสอบ DIM, UserID, ชื่อผู้ใช้, UserTel, UserMail
DIM MyComm, MyRst
รหัสผู้ใช้ = 1
'checklogin() เป็นฟังก์ชันที่กำหนดเองเพื่อตรวจสอบว่าผู้เยี่ยมชมเข้าสู่ระบบหรือไม่
checklg = เช็คอิน()
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
กับMyComm
.ActiveConnection = MyConStr 'MyConStr คือสตริงการเชื่อมต่อฐานข้อมูล
.CommandText = "getUserInfo" 'ระบุชื่อกระบวนงานที่เก็บไว้
.CommandType = 4 'แสดงว่านี่เป็นขั้นตอนการจัดเก็บ
.Prepared = true 'ต้องคอมไพล์คำสั่ง SQL ก่อน
.Parameters.append .CreateParameter("@userid",3,1,4,UserID)
.Parameters.append .CreateParameter("@checklogin",11,1,1,checklg)
SetMyRst = .ดำเนินการ
ลงท้ายด้วย
Set MyComm = Nothing
'รับค่าจากชุดเรคคอร์ดชุดแรก
ชื่อผู้ใช้ = MyRst(0)
'รับค่าจากชุดระเบียนที่สอง
ถ้าไม่ใช่ MyRst ก็ไม่มีอะไรแล้ว
ตั้งค่า MyRst = MyRst.NextRecordset()
UserTel = MyRst(0)
UserMail = MyRst(1)
สิ้นสุดถ้า
ตั้งค่า MyRst = ไม่มีเลย
ในโค้ดข้างต้น วิธี NextRecordset ของวัตถุ Recordset จะถูกนำมาใช้เพื่อรับชุดระเบียนหลายชุดที่ส่งกลับโดยกระบวนงานที่เก็บไว้
จนถึงตอนนี้ บทความนี้ได้ให้คำอธิบายที่ค่อนข้างครอบคลุมเกี่ยวกับสถานการณ์ต่างๆ ที่ ASP เรียกกระบวนงานที่เก็บไว้ สุดท้ายนี้ เรามาพูดถึงวิธีการต่างๆ ในการเรียกโพรซีเจอร์ที่เก็บไว้หลายขั้นตอนในโปรแกรม ASP
ในโปรแกรม ASP อย่างน้อยสามวิธีต่อไปนี้สามารถเรียกใช้โพรซีเดอร์ที่เก็บไว้หลายขั้นตอนได้:
1. สร้างออบเจ็กต์ Command หลายรายการ
DIM MyComm
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
'เรียกกระบวนงานที่เก็บไว้หนึ่ง
-
ตั้งค่า MyComm = ไม่มีเลย
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
'เรียกขั้นตอนที่เก็บไว้ที่สอง
-
ตั้งค่า MyComm = ไม่มีเลย
......
2. สร้างเฉพาะออบเจ็กต์ Command และเมื่อวางสาย ให้ล้างพารามิเตอร์
DIM MyComm
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
'เรียกกระบวนงานที่เก็บไว้หนึ่ง
-
'ล้างพารามิเตอร์ (สมมติว่ามีสามพารามิเตอร์)
MyComm.Parameters.delete 2
MyComm.Parameters.delete 1
MyComm.Parameters.delete 0
'เรียกกระบวนงานที่เก็บไว้ที่สองและล้างพารามิเตอร์
-
Set MyComm = Nothing
ในขณะนี้ โปรดทราบ: ลำดับการล้างพารามิเตอร์อยู่ตรงข้ามกับลำดับการประกาศพารามิเตอร์ ฉันไม่ทราบเหตุผล
3. ใช้วิธีการรีเฟรชของการรวบรวมข้อมูลพารามิเตอร์เพื่อรีเซ็ตวัตถุพารามิเตอร์
DIM MyComm
ตั้งค่า MyComm = Server.CreateObject("ADODB.Command")
'เรียกกระบวนงานที่เก็บไว้หนึ่ง
-
'รีเซ็ตออบเจ็กต์พารามิเตอร์ทั้งหมดที่มีอยู่ในการรวบรวมข้อมูลพารามิเตอร์
MyComm.Parameters.Refresh
'เรียกขั้นตอนที่เก็บไว้ที่สอง
-
Set MyComm = Nothing
โดยทั่วไปเชื่อกันว่าการสร้างอ็อบเจ็กต์ซ้ำๆ เป็นวิธีที่มีประสิทธิภาพน้อยกว่า แต่หลังจากการทดสอบ (เครื่องมือทดสอบคือ Microsoft Application Center Test) ผลลัพธ์ที่ไม่คาดคิด:
วิธีที่ 2 >= วิธีที่ 1 >> วิธีที่ 3
ความเร็วการทำงานของวิธีที่ 2 มากกว่าหรือเท่ากับวิธีที่ 1 (สูงกว่าประมาณ 4%) ความเร็วการทำงานของทั้งสองวิธีนี้เร็วกว่าวิธีที่ 3 มาก (มากถึง 130%) ดังนั้นจึงแนะนำให้ใช้ วิธีที่ 1 เมื่อมีพารามิเตอร์หลายตัว หากไม่มี ให้ใช้วิธีที่ 2
ฉันใช้เวลาหนึ่งวันในการเขียนประสบการณ์ผิวเผินบางส่วนของฉันในการเรียกกระบวนงานที่เก็บไว้ใน ASP ในที่สุด ในหมู่พวกเขาบางคนฉันรู้แค่ผลแต่ไม่รู้สาเหตุและบางคนอาจผิด แต่ทั้งหมดนี้เป็นผลมาจากการปฏิบัติส่วนตัวของฉัน โปรดยอมรับมันอย่างมีวิจารณญาณผู้อ่าน ท่านใดมีความเห็นแตกต่าง กรุณาแจ้งให้ทราบล่วงหน้าครับ.