בשאלה שנשאלה בפורום של ארגון מפתחי ה- ASP הישראלי רצה השואל לדעת כיצד אפשר לעדכן מספר טבלאות הקשורות ביניהם בשאילתה אחת. אפשר - ע"י שימוש ב- UPDATE של ADO ובשאילתה מסוג DATASHAPE.
בדוגמא הבאה קיימות בבסיס הנתונים 2 טבלאות, טבלת Headers מכילה 2 שדות ID שהוא שדה IDENTITY ו title שהוא שדה מסוג varchar. הטבלה השניה Header_Desc מכילה 3 שדות ID כ- IDENTITY HeaderId הנו ה ID של השדה המגביל בטבלת HEADERS ו description הנו שדה מסוג varchar.
טעינת הנתונים
הקובץ Update_Datashape.asp מציג את הנתונים של 2 הטבלאות בצורה הירארכית: <%@ Language=VBScript %>
<%
Response.CharSet= "ISO-8859-8-i"
Set oConn = Server.CreateObject("ADODB.Connection")
ConnStr = "Driver={SQL Server};Server=Mysev;Provider=MSDataShape;"
ConnStr = ConnStr & "Uid=;Pwd=;Database=Mydb;AutoTranslate=No"
oConn.Open ConnStr
%>
שאילתת ה DATASHAPE הבאה תביא רקורדסט שמכיל את הנתונים משתי הטבלאות בצורה הירארכית: <%
SQL = "SHAPE {select * from headers} APPEND"
SQL = SQL & "({ select * from header_desc} RELATE Id TO headerid) AS LEVEL"
set rsDS = oConn.Execute(SQL)
%>
הצגת הנתונים
את הנתונים הכנסתי לתוך שדה טקסט כדי שאפשר יהיה לעדכן אותם, נוסף על כך הוספתי Chekbox -ים, הצקבוקסים המסומנים יהיו אלו שנתוניהם יעודכנו, כמובן שאפשר לבצע את הרישום של איזה רשומות שונו ע"י צד קליינט סקריפט שיכניס לשדה HIDDEN את הנתון על מספר הרשומה שעודכנה. השמות של כל האובייקטים הם שמות זהים בכדי ליצור מערכים בהעברת הנתונים ע"י POST ולדוג מתוכם את האלמנטים במערכים שעברו שינוי.
את ביצוע פעולת העידכון נבצע בתוך IFRAME בכדי לראות את שורות הדיבאגינג:
קובץ העדכון Update_Datashape1.asp: <%@ Language=VBScript %>
<%
Response.CharSet= "ISO-8859-8-i"
%>
כדי שנהיה בטוחים שלא התקבלה שגיאה כי לא סומן אחד הצקבוקסים נעצור את התוכנית עוד לפני שהתחילה. <%
if request("chkData") = "" then
Response.Write "חובה לסמן לפחות צקבוקס אחד בכדי שהדמו יפעל"
Response.End
end if
%>
<%
Set oConn = Server.CreateObject("ADODB.Connection")
ConnStr = "Driver={SQL Server};Server=mysrv;Provider=MSDataShape;"
ConnStr = ConnStr & "Uid=;Pwd=;Database=nydb;AutoTranslate=No"
oConn.Open ConnStr
%>
נרשום את המערך של הצקבוקסים שסומנו <%
response.write request("chkData") & " "
%>
נפרק את המערכים לגורמים <%
newlev1=split( request("lev1"),",")
newdata=split( request("lev2"),",")
newchecked=split( request("chkData"),",")
%>
נייצר שוב שאילתת Datashape רק שבהבדל אחד, מתוך הטבלה השניה נביא רק את הרשומות שאמורות להתעדכן. <%
set rsDS=server.CreateObject("ADODB.Recordset")
SQL = "SHAPE {select * from headers} APPEND"
SQL = SQL & "({ select * from header_desc where id in (" & request("chkData") & ")} “ & _
" RELATE Id TO headerid) AS LEVEL"
response.write sql & " "
rsDS.CursorLocation = 3
rsDS.Open SQL, oConn,1,4, adCmdTable
chkCounter=0
chkCounterlev1=0
%>
כאשר נרוץ על הרקורדסט שקיבלנו נעדכן את הרשומות בתוך הרקורדסט, רק לאחר שעברנו על כל הרקורדסט המשני נבצע פעולת Updatebatch, ובסוף נבצע פעולת Updatebatch על הרקורדסט הראשי. <%
while not rsDS.eof
rsDS.fields(1).Value = newlev1(chkCounterlev1)
set lev2=rsDS.fields("LEVEL").value
chkCounter= chkCounter
while not lev2.eof
response.write newdata(newchecked(chkCounter)-1)& " "
lev2.fields(2).Value = newdata(newchecked(chkCounter)-1)
chkCounter= chkCounter + 1
lev2.movenext
wend
lev2.UpdateBatch
chkCounterlev1=chkCounterlev1 + 1
rsDS.movenext
wend
rsDS.UpdateBatch
rsDS.Close
%>
תכנות נעים!
|