מציאת התאמות לפי קריטריונים גמישים

31/08/2010

בפורום בסיסי נתונים שבתפוז הופיעה שאלה לגבי התאמת מועמדים למכללות: יש מועמדים כשלגבי כל אחד יש נתונים אם שירת בצבא, יש לו בגרות, עשה  יח"ל במתימטיקה וכו'; ויש מכללות שתנאי הקבלה שלהן יכולים לכלול חלק מהסעיפים הנ"ל; ויש למצוא איזה מועמד מתאים לאיזו מכללה. הפתרון הראשון שעלה בדעתי הוא לצרף לטבלת המועמדים עמודות כן/לא בהתאם לתנאים, לצרף לטבלת המכללות עמודות כן/לא בהתאם, ולשלוף כך: Select * From Students S Inner Join Universities U On S.Army>=U.Army And S.Bagrut>=U.Bagrut And S.Math5>=U.Math5; Go הבעייה בפתרון הוא היעדר גמישות:...
אין תגובות

הנפה של ארטוסתנס

27/08/2010

הנפה של ארסטותנס היא אלגוריתם למציאת כל המספרים הראשוניים מ-2 ועד לערך שנקבע מראש: 2 הוא הראשוני הראשון ולכן נמחק את כל המספרים שמתחלקים ב-2 המספר הכי קטן מעל 2 הוא ,3 מכאן שהוא ראשוני, ולכן נמחק את כל המספרים שמתלקים ב-3 המספר הכי קטן מעל 3 הוא 5 (4 כבר נמחק בתור כפולה של 2) ולכן נמחק את כל כפולותיו.. כך ממשיכים עם כל הרשימה, כשלמעשה מספיק להמשיך עד לשורש של הערך המקסימלי ברשימה.. נכין טבלת מספרים מאונדקסת מ-2 ועד 1,000,000: If Object_Id('T_Misparim') Is Not Null Drop Table T_Misparim; Go Declare @N Int=1000000; With T As (Select 2 Mispar Union All Select Mispar+1 From ...

טרנזקציות, שגיאות ושגרות שגיאה: השימוש באופציית Xact_Abort ובפונקציה Xact_State

23/08/2010

האופציה Xact_Abort מגדירה אם בשעת שגיאה לעצור את הריצה ולבצע Rollback לטרנזקציה (On) או לא (Off), כאשר האופציה השניה היא ברירת המחדל. הפונקציה Xact_State קובעת האם יש טרנזקציה פתוחה (1) או אין טרנזקציה פתוחה (0); וכן האם יש טרנזקציה פתוחה שלא ניתן לבצע לה Commit אלא רק Rollback בשל שגיאה (1-). דוגמה 1 – ניצור טבלה עם Primary Key (אסור להכניס ערכים כפולים), ונראה מה קורה במקרה של Xact_Abort Off (ברירת החמדל): Use tempdb; Go If Object_Id('T','U') Is Not Null Drop Table T; Go Create Table T(A Int Not Null Primary Key); Go Set Xact_Abort Off;--ברירת מחדל Select 1 N, 'Before...

טבלת מספרים ראשוניים בדרך איטרטיבית

18/08/2010

בפוסט זה הצעתי דרך לחישוב מספרים ראשוניים על ידי שליפה אחת (CTE רקורסיבי כפול – ליתר דיוק). כאן אני מציע דרך איטרטיבית שהיא יותר יעילה, כשהרעיון באופן כללי הוא כזה: כשבודקים אם מספר מסויים הוא ראשוני – יש לנסות ולחלק אותו בכל המספרים הראשוניים שהם קטנים או שווים לשורש הריבועי שלו (או בהיעדר טבלה של מספרים ראשוניים – וזה בדרך כלל המצב – מחלקים אותו בכל המספרים השלמים בין 2 לבין השורש הריבועי שלו). ההיגיון כאן הוא די ברור – אם מספר מתחלק במספר הגדול מהשורש שלו – התוצאה תהיה קטנה מהשורש שלו, ממילא הוא מתחלק גם בה. למשל- 100 מתחלק ב-20...
אין תגובות

מחיקת שורות ישנות מטבלאות גדולות

12/08/2010

נדרשנו למחוק נתונים ישנים מטבלאות גדולות: הגדולה שבהם בת כ-650,000,000 והאחרות אולי קטנות יותר אבל יחד מצטברות לנפח אחסון גדול ומיותר. ניסינו בהתחלה בתמימותנו – לבצע 'Delete From MyTbl Where Taarih<='20091231 כלומר- למחוק את כל מה שמשנת 2009 ודרומה, אבל זה הסתיים בתקיעת השרת למשך שעות ארוכות וניפוח הלוג למימדים מפלצתיים; ולבסוף עצרנו את המחיקה. החלטנו לעשות זאת בשלבים- כתבנו פרוצדורה שמתחילה מהתאריך הקטן ביותר בטבלה, מוחקת בלולאה את 50,000 הרשומות הראשונות ממנו בכל איטרציה, ועוברת לתאריך הבא בתור: Create Procedure MyProc As Declare @D DateTime, @RC Integer; Select @D=(Select MIN(Taarih) From MyTbl), ...

מספור אוטומטי – עמודת Identity

11/08/2010

Identity היא תכונה ההופכת עמודה מספרית של שלמים לעמודת מספור אוטומטי, כאשר ניתן להגדיר לה מספר התחלתי (Seed) וקבוע גידול (Increment); וברירת המחדל אם לא הוגדר אחרת - (1,1), כלומר- רצף המספרים הטבעיים החל מ-1. נגדיר שתי טבלאות עם עמודת Identity, ולאחת מהם נוסיף View הפונה אליה: Use tempdb; Go Create Table T1(ID Int Identity); Go Create View V1 As Select * From T1; Go Create Table T2(ID Int Identity(1000,10) Unique Clustered, Shem Varchar(50), ...

שירשור ערכים מטבלה

02/08/2010

נפתח בחידה בעל פה: מה יהיה הפלט של הסקריפט הקצר הבא? Declare @S Varchar(Max); Select @S=name From sys.sysobjects; Print @S; נו טוב- הרוב בוודאי ממשיכים הלאה לראות מה התשובה בלי לנסות לחשוב, ומבין מעט הצדיקים שעוצרים לרגע ומנסים את כוחם – חלק אולי כבר יודעים את התשובה, חלק מבינים שיש כאן מלכודת ולא שאלת תם, ואולי יש צדיק אחד שנופל בפח הלא מוצלח.. לעצם העניין – אתם אמורים לטעות ולטעון שהתוכנית תיכשל מכיוון שלתוך משתנה ניתן להכניס ערך אחד ולא עמודה שלמה, עובדה שפקודה כמו (Select @S=(Select name From sys.sysobjects נכשלת מכיוון ששאילתת...