וובמאסטר - תיכנות ובניית אתרים

שליפת רשומות בסדר רנדומאלי באקסס

אוריקס/‏ 7 מאי, 2004
F+
F-
במאמר זה אסביר כיצד ניתן לשלוף רשומות בסדר אקראי ברמת ה SQL ומתוך מסד הנתונים Ms Access.
קודם כל נגדיר את הבעיה שלנו:
באקסס אכן קיימת פונקציה (Rnd) שמטרתה להגריל את סדר שליפת הרשומות, אך בשימוש בה נוצרת בעיה: הפונקציה מגרילה את הסדר פעם אחת, ובשליפות הבאות שולחת את אותו הסדר בדיוק.
לכן עלינו להתגבר על הבעיה בכך שניצור רנדומליות בעצמינו. הדבר היחידי הדרוש לשם כך הוא עמודת מספור אוטומטי, נקרא לה ID לצורך העניין.

השיטה שבה נשתמש היא עשיית פעולות מתמטיות על עמודת ה ID בצורה ש"תבלגן" את הסדר. נשאלת השאלה - איך?
ניקח, לדוגמה, את הצהרת ה SQL הבאה:

1
2  
SELECT ID, sTerm FROM tbl_Terms
ORDER BY ID DESC


נשלב בה פעולות מתמטיות פשוטות:

1
2  
SELECT ID, sTerm FROM tbl_Terms
ORDER BY ((ID*2)+4)/3 DESC


בהצהרה זו עשינו פעולות מסוימות על השדה ID. כשננסה לקרוא את תוכן השדה, נראה שהוא קיבל ערך "חדש" (רק לצורך השליפה, כמובן... דבר לא התעדכן במסד נתונים).

נחזור לבעיה שלנו. פעולות אילו אמנם ישנו את תוכן השדה ID, אך לא יגרמו לשינוי הסדר. הרשומה הראשונה - תישאר ראשונה, השנייה - תישאר שנייה, וכו'...

לצורך יצירת הרנדומליות - נשתמש בטריגונומטריה. הפונקציות הטריגונומטריות הבסיסיות (סינוס, קוסינוס, טנגנס) הן פונקציות שאקסס יודע לעבוד איתן.

נביט על הגרפים הבאים:

אנו רואים שהפונקציות הללו לא לינאריות. כלומר, מצב כמו: "ככל שנציב מספר גדול יותר, כך נקבל תוצאה גבוהה יותר" לא מתקיים במקרה הזה.
את העניין הזה נוכל לנצל לטובתנו: אם נעשה פעולות טריגונומטריות על השדה ID, נוכל להגיע לתוצאה אשר תגרום לאקראיות הסדר.

1
2  
SELECT ID, sTerm FROM tbl_Terms
ORDER BY (sin(ID*35)*cos(ID+55)/(tan(ID+13))*(tan(ID*17)))*(Sin(ID)) DESC


הצהרת ה SQL הזאת גורמת במידה מסוימת לשינוי הסדר, אך שוב אנו נתקלים באותה הבעיה: בכל פעם שנפעיל את ההצהרה יוחזר אותו הסדר.
נתגבר על בעיה זו בכך שנכניס מספרים אקראיים להצהרת ה SQL, ובכך נגרום לזה שבכל פעם שהצהרה זו תופעל - היא תופעל עם מספרים שונים.

לדוגמה:
נגריל מספר באופן הבא:

1  
var z=Math.random()*6;


עכשיו נשלב אותו בהצהרת ה SQL שלנו:

1
2  
Sql = "SELECT ID, sTerm FROM tbl_Terms "
Sql+= " ORDER BY (sin(ID)*cos(ID)/(tan(ID" + z "))*(tan(ID)))*(Sin(ID*"+z+")) DESC"


הצלחנו לגרום לכך שבכל פעם שתופעל הצהרת ה SQL - היא תופעל עם מספר שונה. האופן שבו גרמנו לאקראיות הסדר והעובדה שהגרלנו מספר אחד, גורמים לכך שהסדר אינו מספיק רנדומלי.
כדי להשיג רנדומליות גבוהה יותר נשתמש בהצהרה מורכבת יותר עם מספרים אקראיים רבים יותר:

1
2
3
4
5
6  
var w=Math.random()*4;
var x=Math.random()*10;
var y=Math.random()*3;
var z=Math.random()*6;
var SQL="SELECT ID, sTerm FROM tbl_Terms "
SQL+= "ORDER BY cos("+z+"*(sin(cos(-Sin(tan(sqr(id)*"+y+"))*tan(id)*sin(id*tan(id)))/2*"+x+"*tan(id))))*sin(id*tan(id*cos(id)*cos(id)*Sin(id*tan(id*cos(id)))*tan(90-id*cos(id)*sin(id)))*sin("+w+")*cos(id)) DESC";


כך דאגנו לאקראיות מספקת.
בדוגמא הזו
אנו יכולים לראות כיצד כל רשומה מקבלת מספר אקראי שונה.

הקוד המלא:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33  
<%@ Language=JavaScript Codepage=1255%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title> Random </title>
</head>

<body>
<%
var connDSN="Provider=Microsoft.Jet.OLEDB.4.0; Data Source = "+Server.MapPath("db.mdb")
var oCon =Server.CreateObject("ADODB.connection");
oCon.Open (connDSN);
var oRs=Server.CreateObject("ADODB.Recordset")
var w=Math.random()*4;
var x=Math.random()*10;
var y=Math.random()*3;
var z=Math.random()*6;
var SQL="SELECT ID, sTerm FROM tbl_Terms "
SQL+="ORDER BY cos("+z+"*(sin(cos(-Sin(tan(sqr(id)*"+y+"))*tan(id)*sin(id*tan(id)))/2*"+x+"*tan(id))))*sin(id*tan(id*cos(id)*cos(id)*Sin(id*tan(id*cos(id)))*tan(90-id*cos(id)*sin(id)))*sin("+w+")*cos(id)) DESC";
oRs.Open(SQL,oCon)
Response.Write ("<table><tr><td>")
Response.Write (oRs.GetString(2,-1, "</td><td>", "</td></tr><tr><td>", "-null-"))
Response.Write ("</td></tr></table>")
oRs.Close
oRs = null;
delete oRs;
oCon.Close
oCon = null;
delete oCon;
%>
<hr>
</body>
</html>


אם נרצה לשלוף רשומה אקראית אחת בלבד, נשתמש ב-TOP:

1
2  
var SQL="SELECT TOP 1 ID, sTerm FROM tbl_Terms "
SQL+="ORDER BY cos("+z+"*(sin(cos(-Sin(tan(sqr(id)*"+y+"))*tan(id)*sin(id*tan(id)))/2*"+x+"*tan(id))))*sin(id*tan(id*cos(id)*cos(id)*Sin(id*tan(id*cos(id)))*tan(90-id*cos(id)*sin(id)))*sin("+w+")*cos(id)) DESC";


לחץ כאן להרצת הדוגמא
לחץ כאן להורדת הדוגמא

תגיות: SQL‏  /  אקסס‏  /  access‏  /  אקראי‏  /  random‏  

תגובות בפייסבוק

תגובות למאמר



תגיות פופולאריות

X
הצטרף לעמוד שלנו בפייסבוק להישאר מעודכן!
וובמאסטר © כל הזכויות שמורות