הבלוג של גרי רשף

25/11/2010

מגבלות ה-Sequence ופריצתן

Filed under: Uncategorized — תגיות: , , , — גרי רשף @ 21:21

כמה ימים לאחר שפירסמתי את הפוסט שלי לגבי Sequence – מספור אוטומטי משותף, פרסם איציק בן-גן פוסט באותו נושא, ומה לעשות- חוץ מזה שהוא תותח מבחינה טכנית, הוא מבין את הפילוסופיה של ה-SQL לעומק – והבנה כזו לא פוגשים הרבה; ואני מתייחס כאן בעיקר לכך שהוא הראה ששליפה כפולה מ-Sequence בסגנון של

Select    Next Value For MySeq ID1,

        Next Value For MySeq ID2;

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

במילים אחרות- ה-Sequence אינו טבלה שכל Next שולף ממנה ערך נוסף, אלא אובייקט שיש לו ערך שוטף והוא זה שמוצג; או לחילופין- אם ניצור טבלה עם עמודת Identity בשם 1ID ועמודה מחושבת המציגה את ערכה של עמודת ה-Identity – שתיהן יציגו אותו ערך ולא תתבצע שליפה כפולה של ה-Identity.

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

בצד העובדה שה-Sequence חייב להיות אחיד בתוך הרשומה, הוא אינו יכול להיות אחיד בין הרשומות: לא ניתן לשכפל On The Fly את הערך השוטף בין מספר רשומות, למשל:

Select    *

From    sys.objects

Cross Join (Select Next Value For MySeq ID) T;

פקודה זו לא תחזיר אותו ערך לכל השורות מהטבלה אלא תיצור שגיאה:

Msg 11719, Level 15, State 1, Line 4

NEXT VALUE FOR function is not allowed in check constraints, default objects, computed columns, views, user-defined functions, user-defined aggregates, sub-queries, common table expressions, or derived tables.

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

נו טוב- תמיד ניתן למצוא איזו פירצה, למשל בעזרת OpenRowset..

קודם כל נקנפג את המערכת- מכיוון שהתקנו את השרת עם גרסת Denali CTP1 רק לאחרונה- ספק אם כבר עשינו זאת:

Exec sp_Configure 'show advanced options', 1;

Reconfigure;

Go


Exec sp_configure 'Ad Hoc Distributed Queries', 1;

Reconfigure;

Go

וכעת נשלוף שני ערכים עוקבים באותה שורה:

Select    *,

        Next Value For MySeq ID1

From    Openrowset ('Sqloledb','Server=localhost;Trusted_Connection=Yes','Set Fmtonly Off Select Next Value For MySeq ID2;') T;

ולחילופין- נשכפל אותו ערך מספר פעמים:

Select    *

From    Openrowset ('Sqloledb','Server=localhost;Trusted_Connection=Yes','Set Fmtonly Off Select Next Value For Reconfigure V1;') T

Cross Join sys.objects;

מודעות פרסומת

2 תגובות »

  1. זה שזה הגיוני – סבבה. אבל פרקטית היה עדיף אחרת. מעניין איך זה באורקל.

    אגב, Openrowset הוא ה-backdoor לכל דבר בערך…

    תגובה של מאיר דודאי — 25/11/2010 @ 22:34

    • גם באוראקל ה-Sequence מתנהג כמתואר כאן, כך שבמיקרוסופט כיוונו לדעת גדולים.. 🙂

      תגובה של גרי רשף — 30/11/2010 @ 18:12


RSS feed for comments on this post. TrackBack URI

כתיבת תגובה

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

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

בלוג בוורדפרס.קום.

%d בלוגרים אהבו את זה: