DCSIMG
DEV - גרי רשף

Browse by Tags

All Tags » DEV (RSS)
מריה זקורדאייב הסבה את תשומת ליבי ליוזמה לבקש ממיקרוסופט להוסיף אופציה לקבל רשימת שגיאות מקלט Insert לא חוקי. במה דברים אמורים? אנחנו מנסים להכניס סט נתונים לטבלה, והפקודה נופלת כי יש שם שורות שגויות: אולי אחת, אולי כמה, אולי כולן. הפקודה עצמה חוקית מבחינת העמודות וסוגי הנתונים, והבעייה היא המפתח של טבלת היעד: 1. שורות עם מפתח שכבר קיים אינן יכולות להיכנס. 2. שורות עם מפתחות כפולים (כלומר – מספר שורות עם אותו מפתח בקלט) שאינם קיימים בטבלת היעד – כשרק אחת יכולה להיקלט. היינו שמחים לו בצד אופציות כמו...
Float הוא סוג נתון מספרי שאינו מוגדר במדוייק ויכול לשמש גם למספרים גדולים מאוד (ספרות משמאל לנקודה) וגם למספרים קטנים מאוד (ספרות מימין לנקודה). מבחינה זו עלול המשתמש הטירון לטעות ולחשוב: "למה לי להסתבך עם ה-Decimal שמחייב הגדרה מדוייקת של דיוק מימין ומשמאל לנקודה ושבדיעבד עלול להתברר שהדיוק אינו מספיק? אשתמש ב-Float והמערכת כבר תדע להתאים אותו לכל מספר!". לא ככה? ממש לא: הגמישות הזו היא בעוכרינו, באה על חשבון הדיוק וטומנת בחובה הפתעות; ובדטבייס כמו בכביש – הפתעות זה לא דבר טוב, או כמו...
כשמטפלים במספרים גדולים מאוד מבחינת ערכם המוחלט (כלומר- מספר הספרות משמאל לנקודה) או קטנים מאוד מבחינת ערכם המוחלט (כלומר- מספר הספרות מימין לנקודה) – Decimal הוא אפשרות שתספק את רוב צרכינו; כולל מקרים בהם יש לטפל במספרים שלמים גדולים מאוד שאפילו BigInt מרים ידיים לעומתם.. סוג הנתון הזה מקבל שני פרמטרים המציינים כמה ספרות בסה"כ וכמה מתוכן מימין לנקודה. למשל (Decimal(38,12 מציין שניתן לדייק עד 12 ספרות מימין לנקודה (שברים עשרוניים) ועד 38-12=26 ספרות משמאל לנקודה: Declare @I Decimal (38,12)=12345678901234567890123456...
והרי שאלה שהגיע זה עתה לשולחן המערכת (אפרופו שולחנות..) מאלמוני שהחליט להקים מסעדה וזקוק למערכת שתאפשר לו להקצות שולחנות לפי הזמנות, ולקבל דוח עדכני אילו שולחנות עדיין פנויים ומתי. נו טוב- למען ההגינות עלי לציין שכנראה לא מדובר בשף ותיק ומפורסם עתיר כוכבי מישלן , אלא בסטודנט צעיר ואלמוני שנדרש להגיש פרוייקט לצורך קבלת תעודה מקצועית.. יחד עם זאת- בפני הבלוג שלי כולם שווים, ולא אשיב פני איש ריקם! ניצור טבלת הזמנות ונאכלס אותה בנתונים – חלקם "רגילים" וחלקם נתוני קצה כדי לא ליפול "בפינות"...
מה שטרד היום את מנוחתי לא היה האיום האיראני, לא האזהרות מפני רעידת אדמה ממשמשת ובאה, ואף לא הגרעון בתקציב; אלא מה קורה כשמשלבים באותה שליפה פקודות Union (שמבצעת Distinct) ו-Union All.. הנתונים: Create Table #T(N Int ); Go   Insert Into #T Select 1; Insert Into #T Select 2; Insert Into #T Select 2; Insert Into #T Select 3; Insert Into #T Select 3; Insert Into #T Select 3; Go   Select * From #T; והשליפות לבדיקה: Select * From #T Union All Select * From #T Union Select * From #T;   Select...
בגרסאות 2005 – 2008R2 שליפה של דפים, למשל כמקובל בדפי אינטרנט שמחזירים חלק מהתוצאות, הייתה יכולה להיעשות באמצעות Row_Number: ממספרים את השורות בסט, ובכל פעם מחזירים "מֵאִייָה" אחרת. אם יש אינדקס על העמודה לפיה התוצאות ממויינות – אזי מה טוב, ניתן לעשות שימוש בו: Use tempdb; Go   If Object_ID( 'T_Messages' , 'U' ) Is Not Null Drop Table T_Messages;   Select * Into T_Messages From sys.messages;   Create Index Idx_T_Messages On T_Messages(Message_ID, Language_ID...
פנה אלי פלוני בשאלה כדלקמן: יש לו טבלה אליה הוא מכניס שורות בעזרת פרוצדורה בכל פרק זמן נתון, והוא רוצה למספר אותן. נניח שהוא הכניס שורות ביום ובשעת כתיבת שורות, אזי בעמודת התאריך יהיה כתוב 29/01/2013 07:29:15, והוא רוצה בנוסף שהשורות של תאריך זה יהיו ממוספרות. הוא מכיר את אופציית ה-Identity ליצירת מספור אוטומטי, אלא שאופציה זו ממספרת בסדר עולה את כל השורות ולא כל תאריך לחוד.. מה עושים? בניגוד לפוליטיקאים שעונים על השאלות המופנות אליהן ב-"לא זו השאלה אלא.." ומנסחים שאלה חלופית עליה יש להם...
האופרטור In (כחלק מפסוקית ה-Where) הוא מאוד פופלרי כשרוצים להשוות בין ערך לרשימת ערכים ללא שימוש ב-Or מסובך. למשל- במקום Where @X=1 Or @X=2 Or @X=3 אפשר בקיצור (Where @X In (1,2,3. יתרוהו הגדול של האופרטור In שהוא פשוט להבנה ונוח לשימוש, ולא פעם משמיצים את ביצועיו שלא בצדק. כל עוד מדובר ברשימה קצרה של מספר ערכים – אין טעם להתעמק בביצועים, אך מה קורה אם מדובר ברשימה ארוכה? אני אבדוק שלוש אפשרויות: 1. In עם רשימת ערכים מפורשת. 2. In הפונה לטבלה (ממופתחת ומאונדקסת לעילא ולעילא). 3. חלופה ל-In כאשר מדובר...
מספרים משוכללים הם מספרים ששווים לסכום המחלקים הקטנים מהם. למשל- 6 מתחלק ב-1,2,3; וסכום הוא 6. 28 מתחלק ב-14,7,4,2,1; וסכומם הוא 28. מספרים ידידים הם צמדי מספרים שסכום מחלקי האחד שווים למשנהו (ולהיפך). למשל- 220 ו-284 הם מספרים ידידים מכיוון שסכום המחלקים של 220 הוא 284 וסכום המחלקים של 284 הוא 220. כדי למצוא יצורים משונים שכאלו ניתן להיעזר בלולאות, אך לא נידרדר לשפל כזה כשניתן להשתמש בטבלת מספרים ולהציג פתרון Set based.. נתחיל מהמשוכללים, כשהפתרון כולו "באוויר"; כלומר- בלי ליצור טבלאות...
נניח שמחפשים עובד שמדבר עברית, ספרדית ואנגלית. איך נמצא אחד כזה? מן הסתם יש לנו טבלאות מתאימות לחיפוש ולא צריך לשלוח מייל בתפוצת נאטו ולחפש מתנדבים, ואזי- איזו שאילתה נריץ? תנו את המשימה הזו לקבוצת מפתחים, וחצי מהם יענו אוטומטית- Select * From MyTable Where Safa= 'עברית' And Safa= 'אנגלית' And Safa= 'ספרדית' ; כמובן שזה לא יעבוד, ולא משנה כיצד נתכנן ונאכלס את הטבלה הזו, מכיוון שלא יכול להיות שיהיה ערך ששווה גם 'עברית' גם 'אנגלית' וגם 'ספרדית'.. "אה...
Posted by גרי רשף | 1 comment(s)
תגים:, ,
שאלה שהגיעה לשולחן המערכת: נתונה רשימת מספרים- 407.16, 536.82, 1187.03, 923.94, 80.39, 651.46, 1547.90, 119.99, 110.66, 621.76, 62.6, 1616.24, 227.85, 878.06, 824.76, 950.04, 1125.95, 208.80, 2004.48, 3358.20, 1272.52 ואנחנו מעניינים למצוא תת קבוצה שלה שסכום איבריה הוא 14007.70. כשיש בעייה תמיד עוזר לדעת מה הפתרון- 407.16, 536.82, 1187.03, 1547.90, 119.99, 110.66, 62.6, 1616.24, 227.85, 878.06, 824.76, 1125.95, 2004.48, 3358.20 אצלנו אין רשימות או קבוצות, אלא רק טבלאות, ולפני שנתחיל לדבר- קודם כל...
כאשר יוצרים אינדקס על טבלה לפי עמודה1, עמודה2, עמודה3; הדעת נותנת שהוא יהיה שימושי כשנבצע חיפוש או מיון לפי עמודה1, עמודה2, עמודה3.. מה יקרה אם נחפש לפי עמודה2 דווקא? למשל- יש לנו טבלת מכירות בה העמודה הראשית באינדקס היא התאריך, והעמודה המשנית המוכר; ואנחנו מעוניינים לבצע חיפוש לפי מוכר.. השכל הישר (שלי לפחות) אומר שזה תלוי בסלקטיוויות של העמודה הראשית: אם הסלקטיוויות נמוכה אז כדאי ואם היא גבוהה – לא. כלומר- אם בטבלת המכירות הנ"ל יש רק שני תאריכים שונים (על פני הרבה מאוד שורות) ואנחנו מחפשים...
פרסמתי לפני מספר ימים פוסט שהשווה את הביצועים של In ושל Not In עם החלופות השונות , וציינתי מספר פעמים שהמערכת במקרה של In מבצעת Table Scan (בהנחה שאין אינדקס מתאים) עבור כל שורה מהטבלה הראשית כדי לבדוק אם היא נמצאת במשנית, ועוצרת את החיפוש כשהיא מוצאת כי אין צורך לחפש התאמות נוספות כשדי באחת כדי להציג אותה; ובמקרה של Not In מבצעת באופן דומה אך הפוך Table Scan עבור כל שורה מהטבלה כדי לבדוק אם היא במשנית, וכשהיא מוצאת היא עוצרת כי די בכך כדי לא להציג אותה. אם לצטט פתגם סיני עתיק- כדי לדעת שהביצה מקולקלת...
כשהייתי בראשית דרכי ב-SQL Server, שמעתי באחד הכנסים ש"בדקו ומצאו" שהשימוש ב-Inner Join מעט יותר יעיל מאשר השימוש ב-In. אינני זוכר בוודאות ממי שמעתי את זה, אך עובדה שבמשך שנים התייחסתי לכך כאל תורה מסיני, ואף ציטטתי זאת בידענות פה ושם. לאחרונה כשנזכרתי בכך, קמטתי את מצחי ותהיתי האמנם.. דווקא הנסיון והידע שצברתי מאז הובילו אותי לחשוב כיום שאולי דווקא In יעיל יותר: בניגוד ל-Join בו לכל שורה מצד ה-From יש למצוא את כל ההתאמות בצד ה-Join, ב-In יש למצוא רק את ההתאמה הראשונה.. ואם כבר- אז מה עם...
בעייה שניתקלתי בה לאחרונה: נתונה טבלה ובה מחרוזות, ויש לבדוק ולהשוות כל אחת מהן למחרוזת חיצונית ולבדוק כמה התאמות יש (כלומר- כמה "בולים" יש כמקובל במשחק בול-פגיעה). לדוגמה- טבלה עם מספר מחרוזות (במקרה זה מחרוזות של ספרות אך ניתן גם תווים אחרים): Create Table #T(ID Int Primary Key , Nm Varchar (20)); Go   Insert Into #T Select 1,1230007590 Insert Into #T Select 2,5656781123 Insert Into #T Select 3,3235577910 Insert Into #T Select 5,0235879421 Insert Into #T Select 4,8224479590 Go  ...
More Posts Next page »