نظرات مطالب
مفهوم READ_COMMITTED_SNAPSHOT در EF 6
خبری در اینباره از تیم SQL Server بعدی
اطلاعات بیشتر
The Hekaton team also found that multi-version concurrency control (MVCC) proved robust in scenarios with higher workloads and higher contention
Many applications have a need to keep audit information on changes made to objects in the database. Traditionally, this would be done either through log events, stored procedures that implement the logging, or the use of archive/tombstone tables to store the old values before the modification (hopefully enforced through stored procedures). With all of these, there is always a chance that a developer could forget to do those things in a specific section of code, and that changes could be made through the application without logging the change correctly. With Entity Framework 4.1’s DbContext API, it is fairly easy to implement more robust audit logging in your application
مطالب
Roslyn #3
بررسی Syntax tree
زمانیکه صحبت از Syntax میشود، منظور نمایش متنی سورس کدها است. برای بررسی و آنالیز آن، نیاز است این نمایش متنی، به ساختار دادهای ویژهای به نام Syntax tree تبدیل شود و این Syntax tree مجموعهای است از tokenها. Tokenها بیانگر المانهای مختلف یک زبان، شامل کلمات کلیدی، عملگرها و غیره هستند.
در تصویر فوق، مراحل تبدیل یک قطعه کد #C را به مجموعهای از tokenهای معادل آن مشاهده میکنید. علاوه بر اینها، Roslyn syntax tree شامل موارد ویژهای به نام Trivia نیز هست. برای مثال در حین نوشتن کدها، در ابتدای سطرها تعدادی space یا tab وجود دارند و یا در این بین ممکن است کامنتی نوشته شود. هرچند این موارد از دیدگاه یک کامپایلر بیمعنا هستند، اما ابزارهای Refactoring ایی که به Trivia دقت نداشته باشند، خروجی کد به هم ریختهای را تولید خواهند کرد و سبب سردرگمی استفاده کنندگان میشوند.
در تصویر فوق، اشارهگر ادیتور پس از تایپ semicolon قرار گرفتهاست. در این حالت میتوانید دو نوع trivia مخصوص فضای خالی و کامنتها را در syntax visualizer، مشاهده کنید.
به علاوه پس از هر token بازهای از اعداد را مشاهده میکنید که بیانگر محل قرارگیری آنها در سورس کد هستند. این محلها جهت ارائهی خطاهای دقیق مرتبط با آن نقاط، بسیار مفید هستند.
یک Syntax tree از مجموعهای از syntax nodes تشکیل میشود و هر node شامل مواردی مانند تعاریف، عبارات و امثال آن است. در افزونهی Syntax visualizer نودهایی که رنگ قرمز متمایل به قهوهای دارند، بیانگر نودهای Trivia، نودهای آبی، Syntax nodes و نودهای سبز، Syntax token هستند.
مفاهیم این رنگها را با کلیک بر روی دکمهی Legend هم میتوان مشاهده کرد.
تفاوت Syntax با Semantics
در Roslyn امکان کار با Syntax و Semantics کدها وجود دارد.
یک Syntax، از گرامر زبان خاصی پیروی میکند. در Syntax اطلاعات بسیار زیادی وجود دارند که معنای برنامه را تغییر نمیدهند؛ مانند کامنتها، فضاهای خالی و فرمت ویژهی کدها. البته فضاهای خالی در زبانهایی مانند پایتون دارای معنا هستند؛ اما در سیشارپ خیر. همچنین در Syntax، توافق نامهای وجود دارد که بیانگر تعدادی واژهی از پیش رزرو شده، مانند کلمات کلیدی هستند.
اما Semantics در نقطهی مقابل Syntax قرار میگیرد و بیانگر معنای سورس کد است. برای مثال در اینجا تقدم و تاخر عملگرها مفهوم پیدا میکنند و یا اینکه Type system چیست و چه نوعهایی را میتوان به دیگری نسبت داد و تبدیل کرد. عملیات Binding در این مرحله رخ میدهد و مفهوم identifierها را مشخص میکند. برای مثال x در این قسمت از سورس کد، به چه معنایی است و به کجا اشاره میکند؟
خواص ویژهی Syntax tree در Roslyn
- تمام اجزای کد را شامل عناصر سازندهی زبان و همچنین Trivia، به همراه دارد.
- API آن توسط کتابخانههای ثالث قابل دسترسی است.
- Immutable طراحی شدهاست. به این معنا که زمانیکه syntax tree توسط Roslyn ایجاد شد، دیگر تغییر نمیکند. به این ترتیب امکان دسترسی همزمان و موازی به آن بدون نیاز به انواع قفلهای مسایل همزمانی وجود دارد. اگر کتابخانهی ثالثی به Syntax tree ارائه شده دسترسی پیدا میکند، میتواند کاملا مطمئن باشد که این اطلاعات دیگر تغییری نمیکنند و نیازی به قفل کردن آنها نیست. همچنین این مساله امکان استفادهی مجدد از sub treeها را در حین ویرایش کدها میسر میکند. به آنها mutating trees نیز گفته میشود.
- مقاوم است در برابر خطاها. اگر از قسمت اول به خاطر داشته باشید، Roslyn میبایستی جایگزین کامپایلر دومی به نام کامپایلر پس زمینهی ویژوال استودیو که خطوط قرمزی را ذیل سطرهای مشکل دار ترسیم میکند، نیز میشد. فلسفهی طراحی این کامپایلر، مقاوم بودن در برابر خطاهای تایپی و هماهنگی آن با تایپ کدها توسط برنامه نویس بود. Syntax tree در Roslyn نیز چنین خاصیتی را دارد و اگر مشغول به تایپ شوید، باز هم کار کرده و اینبار خطاهای موجود را نمایش میدهد که میتواند توسط ابزارهای نمایش دهندهی ویژوال استودیو یا سایر ابزارهای ثالث استفاده شود.
برای نمونه در تصویر فوق، تایپ semicolon فراموش شدهاست؛ اما همچنان Syntax tree در دسترس است و به علاوه گزارش میدهد که semicolon مفقود است و تایپ نشدهاست.
Parse سورس کد توسط Roslyn
ابتدا یک پروژهی کنسول سادهی دات نت 4.6 را در VS 2015 آغاز کنید. سپس از طریق خط فرمان نیوگت، دستور ذیل را صادر نمائید:
به این ترتیب API لازم جهت کار با Roslyn به پروژه اضافه خواهند شد.
سپس کدهای ذیل را به آن اضافه کنید:
توضیحات:
کار Parse سورس کد دریافتی، بر اساس سرویسهای زبان متناظر با آنها آغاز میشود. برای مثال سرویسهایی مانند VisualBasicSyntaxTree و یا CSharpSyntaxTree مثال فوق که سورس کد مورد آنالیز آن، از نوع سیشارپ است.
این کلاسهای Factory، دارای دو متد Create و ParseText هستند. کار متد ParseText آن مشخص است؛ یک قطعهی متنی از کد را آنالیز کرده و معادل Syntax Tree آنرا تولید میکند. متد Create آن، اشیایی مانند نودهای Syntax visualizer را دریافت کرده و بر اساس آنها یک Syntax tree را تولید میکند.
کار با متد Create آنچنان ساده نیست. به همین جهت یکی از اعضای تیم Roslyn برنامهای را به نام Roslyn Quoter ایجاد کردهاست که نسخهی آنلاین آنرا در اینجا و سورس کد آنرا در اینجا میتوانید بررسی کنید.
جهت آزمایش، همان قطعهی متنی سورس کد مثال فوق را در نسخهی آنلاین آن جهت آنالیز و تولید ورودی متد Create، وارد کنید. خروجی آنرا میتوان مستقیما در متد Create بکار برد.
فرمت کردن خودکار کدها به کمک Roslyn
اگر بر روی tree حاصل، متد ToString را فراخوانی کنیم، خروجی آن مجددا سورس کد مورد آنالیز است. اگر علاقمند بودید که Roslyn به صورت خودکار کدهای ورودی را فرمت کند و تمام آنها را در یک سطر نمایش ندهد، متد NormalizeWhitespace را بر روی ریشهی Syntax tree فراخوانی کنید:
اینبار خروجی فراخوانی فوق به صورت ذیل است:
کوئری گرفتن از سورس کد توسط Roslyn
در ادامه قصد داریم با سه روش مختلف کوئری گرفتن از Syntax tree، آشنا شویم. برای این منظور متد ذیل را به پروژهای که در ابتدای برنامه آغاز کردیم، اضافه کنید:
توضیحات:
روش اول کوئری گرفتن از Syntax tree، استفاده از object model آن است. در اینجا هربار، نوع و Kind هر نود را بررسی کرده و در نهایت به اجزای مدنظر خواهیم رسید. شروع کار هم با دریافت ریشهی syntax tree توسط متد GetRoot و تبدیل نوع آن نود به CompilationUnitSyntax میباشد.
روش دوم استفاده از روش LINQ است؛ با توجه به اینکه ساختار یک Syntax tree بسیار شبیه است به LINQ to XML. در اینجا یک سری نود، ریشه و فرزندان آنها را داریم که با روش LINQ بسیار سازگار هستند. برای نمونه در مثال فوق، در ریشهی Parse شده، در تمام کلاسهای آن، به دنبال متد یا متدهایی هستیم که نام آنها Bar است.
و در نهایت روش مرسوم و متداول کار با Syntax trees، استفاده از الگوی Visitors است. همانطور که در کدهای دو روش قبل مشاهده میکنید، باید تعداد زیادی حلقه و if و else نوشت تا به جزء و المان مدنظر رسید. راه سادهتری نیز برای مدیریت این پیچیدگی وجود دارد و آن استفاده از الگوی Visitor است. کار این الگو ارائهی متدهایی قابل override شدن است و فراخوانی آنها، در طی حلقههایی پشت صحنه که این Visitor را اجرا میکنند، صورت میگیرد. بنابراین در اینجا دیگر برای رسیدن به یک متد، حلقه نخواهید نوشت. تنها کاری که باید صورت گیرد، override کردن متد Visit المانی خاص در Syntax tree است.
هر نود در syntax tree دارای متدی است به نام Accept که یک Visitor را دریافت میکند. همچنین Visitorهای نوشته شده نیز دارای متد Visit یک نود هستند.
نمونهای از این Visitors را در کلاس ذیل مشاهده میکنید:
در اینجا برای رسیدن به تعاریف متدها دیگر نیازی نیست تا حلقه نوشت. بازنویسی متد VisitMethodDeclaration، دقیقا همین کار را انجام میدهد و در طی پروسهی Visit یک Syntax tree، اگر متدی در آن تعریف شده باشد، متد VisitMethodDeclaration حداقل یکبار فراخوانی خواهد شد.
کلاس پایهی CSharpSyntaxWalker از کلاس CSharpSyntaxVisitor مشتق شدهاست و به تمام امکانات آن دسترسی دارد. علاوه بر آنها، کلاس CSharpSyntaxWalker به Tokens و Trivia نیز دسترسی دارد.
نحوهی استفاده از Visitor سفارشی نوشته شده نیز به صورت ذیل است:
در اینجا متد Visit این Visitor را بر روی نود ریشهی Syntax tree اجرا کردهایم.
زمانیکه صحبت از Syntax میشود، منظور نمایش متنی سورس کدها است. برای بررسی و آنالیز آن، نیاز است این نمایش متنی، به ساختار دادهای ویژهای به نام Syntax tree تبدیل شود و این Syntax tree مجموعهای است از tokenها. Tokenها بیانگر المانهای مختلف یک زبان، شامل کلمات کلیدی، عملگرها و غیره هستند.
در تصویر فوق، مراحل تبدیل یک قطعه کد #C را به مجموعهای از tokenهای معادل آن مشاهده میکنید. علاوه بر اینها، Roslyn syntax tree شامل موارد ویژهای به نام Trivia نیز هست. برای مثال در حین نوشتن کدها، در ابتدای سطرها تعدادی space یا tab وجود دارند و یا در این بین ممکن است کامنتی نوشته شود. هرچند این موارد از دیدگاه یک کامپایلر بیمعنا هستند، اما ابزارهای Refactoring ایی که به Trivia دقت نداشته باشند، خروجی کد به هم ریختهای را تولید خواهند کرد و سبب سردرگمی استفاده کنندگان میشوند.
در تصویر فوق، اشارهگر ادیتور پس از تایپ semicolon قرار گرفتهاست. در این حالت میتوانید دو نوع trivia مخصوص فضای خالی و کامنتها را در syntax visualizer، مشاهده کنید.
به علاوه پس از هر token بازهای از اعداد را مشاهده میکنید که بیانگر محل قرارگیری آنها در سورس کد هستند. این محلها جهت ارائهی خطاهای دقیق مرتبط با آن نقاط، بسیار مفید هستند.
یک Syntax tree از مجموعهای از syntax nodes تشکیل میشود و هر node شامل مواردی مانند تعاریف، عبارات و امثال آن است. در افزونهی Syntax visualizer نودهایی که رنگ قرمز متمایل به قهوهای دارند، بیانگر نودهای Trivia، نودهای آبی، Syntax nodes و نودهای سبز، Syntax token هستند.
مفاهیم این رنگها را با کلیک بر روی دکمهی Legend هم میتوان مشاهده کرد.
تفاوت Syntax با Semantics
در Roslyn امکان کار با Syntax و Semantics کدها وجود دارد.
یک Syntax، از گرامر زبان خاصی پیروی میکند. در Syntax اطلاعات بسیار زیادی وجود دارند که معنای برنامه را تغییر نمیدهند؛ مانند کامنتها، فضاهای خالی و فرمت ویژهی کدها. البته فضاهای خالی در زبانهایی مانند پایتون دارای معنا هستند؛ اما در سیشارپ خیر. همچنین در Syntax، توافق نامهای وجود دارد که بیانگر تعدادی واژهی از پیش رزرو شده، مانند کلمات کلیدی هستند.
اما Semantics در نقطهی مقابل Syntax قرار میگیرد و بیانگر معنای سورس کد است. برای مثال در اینجا تقدم و تاخر عملگرها مفهوم پیدا میکنند و یا اینکه Type system چیست و چه نوعهایی را میتوان به دیگری نسبت داد و تبدیل کرد. عملیات Binding در این مرحله رخ میدهد و مفهوم identifierها را مشخص میکند. برای مثال x در این قسمت از سورس کد، به چه معنایی است و به کجا اشاره میکند؟
خواص ویژهی Syntax tree در Roslyn
- تمام اجزای کد را شامل عناصر سازندهی زبان و همچنین Trivia، به همراه دارد.
- API آن توسط کتابخانههای ثالث قابل دسترسی است.
- Immutable طراحی شدهاست. به این معنا که زمانیکه syntax tree توسط Roslyn ایجاد شد، دیگر تغییر نمیکند. به این ترتیب امکان دسترسی همزمان و موازی به آن بدون نیاز به انواع قفلهای مسایل همزمانی وجود دارد. اگر کتابخانهی ثالثی به Syntax tree ارائه شده دسترسی پیدا میکند، میتواند کاملا مطمئن باشد که این اطلاعات دیگر تغییری نمیکنند و نیازی به قفل کردن آنها نیست. همچنین این مساله امکان استفادهی مجدد از sub treeها را در حین ویرایش کدها میسر میکند. به آنها mutating trees نیز گفته میشود.
- مقاوم است در برابر خطاها. اگر از قسمت اول به خاطر داشته باشید، Roslyn میبایستی جایگزین کامپایلر دومی به نام کامپایلر پس زمینهی ویژوال استودیو که خطوط قرمزی را ذیل سطرهای مشکل دار ترسیم میکند، نیز میشد. فلسفهی طراحی این کامپایلر، مقاوم بودن در برابر خطاهای تایپی و هماهنگی آن با تایپ کدها توسط برنامه نویس بود. Syntax tree در Roslyn نیز چنین خاصیتی را دارد و اگر مشغول به تایپ شوید، باز هم کار کرده و اینبار خطاهای موجود را نمایش میدهد که میتواند توسط ابزارهای نمایش دهندهی ویژوال استودیو یا سایر ابزارهای ثالث استفاده شود.
برای نمونه در تصویر فوق، تایپ semicolon فراموش شدهاست؛ اما همچنان Syntax tree در دسترس است و به علاوه گزارش میدهد که semicolon مفقود است و تایپ نشدهاست.
Parse سورس کد توسط Roslyn
ابتدا یک پروژهی کنسول سادهی دات نت 4.6 را در VS 2015 آغاز کنید. سپس از طریق خط فرمان نیوگت، دستور ذیل را صادر نمائید:
PM> Install-Package Microsoft.CodeAnalysis
سپس کدهای ذیل را به آن اضافه کنید:
using System; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; namespace Roslyn01 { class Program { static void Main(string[] args) { parseText(); } static void parseText() { var tree = CSharpSyntaxTree.ParseText("class Foo { void Bar(int x) {} }"); Console.WriteLine(tree.ToString()); Console.WriteLine(tree.GetRoot().NormalizeWhitespace().ToString()); var res = SyntaxFactory.ClassDeclaration("Foo") .WithMembers(SyntaxFactory.List<MemberDeclarationSyntax>(new[] { SyntaxFactory.MethodDeclaration( SyntaxFactory.PredefinedType( SyntaxFactory.Token(SyntaxKind.VoidKeyword) ), "Bar" ) .WithBody(SyntaxFactory.Block()) })) .NormalizeWhitespace(); Console.WriteLine(res); } } }
کار Parse سورس کد دریافتی، بر اساس سرویسهای زبان متناظر با آنها آغاز میشود. برای مثال سرویسهایی مانند VisualBasicSyntaxTree و یا CSharpSyntaxTree مثال فوق که سورس کد مورد آنالیز آن، از نوع سیشارپ است.
این کلاسهای Factory، دارای دو متد Create و ParseText هستند. کار متد ParseText آن مشخص است؛ یک قطعهی متنی از کد را آنالیز کرده و معادل Syntax Tree آنرا تولید میکند. متد Create آن، اشیایی مانند نودهای Syntax visualizer را دریافت کرده و بر اساس آنها یک Syntax tree را تولید میکند.
کار با متد Create آنچنان ساده نیست. به همین جهت یکی از اعضای تیم Roslyn برنامهای را به نام Roslyn Quoter ایجاد کردهاست که نسخهی آنلاین آنرا در اینجا و سورس کد آنرا در اینجا میتوانید بررسی کنید.
جهت آزمایش، همان قطعهی متنی سورس کد مثال فوق را در نسخهی آنلاین آن جهت آنالیز و تولید ورودی متد Create، وارد کنید. خروجی آنرا میتوان مستقیما در متد Create بکار برد.
فرمت کردن خودکار کدها به کمک Roslyn
اگر بر روی tree حاصل، متد ToString را فراخوانی کنیم، خروجی آن مجددا سورس کد مورد آنالیز است. اگر علاقمند بودید که Roslyn به صورت خودکار کدهای ورودی را فرمت کند و تمام آنها را در یک سطر نمایش ندهد، متد NormalizeWhitespace را بر روی ریشهی Syntax tree فراخوانی کنید:
tree.GetRoot().NormalizeWhitespace().ToString()
class Foo { void Bar(int x) { } }
کوئری گرفتن از سورس کد توسط Roslyn
در ادامه قصد داریم با سه روش مختلف کوئری گرفتن از Syntax tree، آشنا شویم. برای این منظور متد ذیل را به پروژهای که در ابتدای برنامه آغاز کردیم، اضافه کنید:
static void querySyntaxTree() { var tree = CSharpSyntaxTree.ParseText("class Foo { void Bar() {} }"); var node = (CompilationUnitSyntax)tree.GetRoot(); // Using the object model foreach (var member in node.Members) { if (member.Kind() == SyntaxKind.ClassDeclaration) { var @class = (ClassDeclarationSyntax)member; foreach (var member2 in @class.Members) { if (member2.Kind() == SyntaxKind.MethodDeclaration) { var method = (MethodDeclarationSyntax)member2; // do stuff } } } } // Using LINQ query methods var bars = from member in node.Members.OfType<ClassDeclarationSyntax>() from member2 in member.Members.OfType<MethodDeclarationSyntax>() where member2.Identifier.Text == "Bar" select member2; var res = bars.ToList(); // Using visitors new MyVisitor().Visit(node); }
روش اول کوئری گرفتن از Syntax tree، استفاده از object model آن است. در اینجا هربار، نوع و Kind هر نود را بررسی کرده و در نهایت به اجزای مدنظر خواهیم رسید. شروع کار هم با دریافت ریشهی syntax tree توسط متد GetRoot و تبدیل نوع آن نود به CompilationUnitSyntax میباشد.
روش دوم استفاده از روش LINQ است؛ با توجه به اینکه ساختار یک Syntax tree بسیار شبیه است به LINQ to XML. در اینجا یک سری نود، ریشه و فرزندان آنها را داریم که با روش LINQ بسیار سازگار هستند. برای نمونه در مثال فوق، در ریشهی Parse شده، در تمام کلاسهای آن، به دنبال متد یا متدهایی هستیم که نام آنها Bar است.
و در نهایت روش مرسوم و متداول کار با Syntax trees، استفاده از الگوی Visitors است. همانطور که در کدهای دو روش قبل مشاهده میکنید، باید تعداد زیادی حلقه و if و else نوشت تا به جزء و المان مدنظر رسید. راه سادهتری نیز برای مدیریت این پیچیدگی وجود دارد و آن استفاده از الگوی Visitor است. کار این الگو ارائهی متدهایی قابل override شدن است و فراخوانی آنها، در طی حلقههایی پشت صحنه که این Visitor را اجرا میکنند، صورت میگیرد. بنابراین در اینجا دیگر برای رسیدن به یک متد، حلقه نخواهید نوشت. تنها کاری که باید صورت گیرد، override کردن متد Visit المانی خاص در Syntax tree است.
هر نود در syntax tree دارای متدی است به نام Accept که یک Visitor را دریافت میکند. همچنین Visitorهای نوشته شده نیز دارای متد Visit یک نود هستند.
نمونهای از این Visitors را در کلاس ذیل مشاهده میکنید:
class MyVisitor : CSharpSyntaxWalker { public override void VisitMethodDeclaration(MethodDeclarationSyntax node) { if (node.Identifier.Text == "Bar") { // do stuff } base.VisitMethodDeclaration(node); } }
کلاس پایهی CSharpSyntaxWalker از کلاس CSharpSyntaxVisitor مشتق شدهاست و به تمام امکانات آن دسترسی دارد. علاوه بر آنها، کلاس CSharpSyntaxWalker به Tokens و Trivia نیز دسترسی دارد.
نحوهی استفاده از Visitor سفارشی نوشته شده نیز به صورت ذیل است:
new MyVisitor().Visit(node);
قبل از ایجاد Sequence در Sql Server 2012، توضیح مختصری را درباره آن میدهم.
در واقع Sequence روشی برای تولید اعداد ترتیبی با قابلیت افزایش یا کاهش عددهای دلخواه میباشد که توسط کاربر یا برنامه نویس ایجاد میشود. بنابراین Sequenceها User-Defined میباشند.
در اینجا ممکن است سئوالی پیش بیاید که اینکار توسط Identity هم قابل انجام است، اما چرا استفاده از Sequence توسط مایکروسافت پیشنهاد میشود.
بدلایل زیر استفاده از Sequence بهتر میباشد:
Syntax آن به شرح ذیل میباشد:
شرح Syntax :
در ادامه با یک مثال ساده، یک Sequence ایجاد مینماییم:
در مثال بالا Start with برابر یک است، یعنی اولین عددی که تولید میشود، برابر یک است،INCREMENT BY برابر یک است یعنی در هر بار فراخوانی Sequence یک عدد به عدد تولید شده قبلی افزوده میشود. مقدار Minvalue برابر یک است، یعنی کمترین مقداری که Sequence میتواند تولید نماید برابر یک است. مقدار Maxvalue برابر 30 است، یعنی بیشترین مقداری که Sequence میتواند تولید نماید برابر 30 میباشد. و Cycle هم برای Sequence فوق در نظر گرفته شده است، بدین مفهوم ، که Sequence به مقدار 30 برسد، Restart شده و از مقدار یک شروع به تولید اعداد مینماید.
برای اینکه بتوانیم مقدار Sequence را بدست آوریم، کافیست از Syntax زیر استفاده نمایید:
به عنوان مثال داریم:
اگر Select بالا را تا 30 بار انجام دهید، برای دفعه 31 مقدار آن یک میشود، چون در زمان تعریف Cycle ،Sequence را انتخاب کرده بودیم. در غیر اینصورت برای دفعه 31 با خطا زیر مواجه میشوید.
یکی از امکانات جالب Sequence این است که شما میتوانید Sequence را روی یک فیلد Sort شده تنظیم نمایید، برای روش شدن مطلب به مثال زیر توجه نمایید:
در ابتدا مطابق Script زیر جدولی را ایجاد و مقادیری را درون آن درج مینماییم:
سپس یک Schema به نام Sample ایجاد میکنیم:
در ادامه یک Sequence به نام Test ایجاد میکنیم:
حال Query زیر را اجرا مینماییم:
در Query بالا روی فیلد Name به صورت صعودی عملیات Sort انجام میشود، و سپس Sequence روی آن اعمال میگردد، برای روشنتر شدن مطلب خروجی را مشاهده نمایید که تعداد رکورد آن 6 میباشد.
امیدوارم مطلب فوق مفید واقع شده باشد.
در واقع Sequence روشی برای تولید اعداد ترتیبی با قابلیت افزایش یا کاهش عددهای دلخواه میباشد که توسط کاربر یا برنامه نویس ایجاد میشود. بنابراین Sequenceها User-Defined میباشند.
در اینجا ممکن است سئوالی پیش بیاید که اینکار توسط Identity هم قابل انجام است، اما چرا استفاده از Sequence توسط مایکروسافت پیشنهاد میشود.
بدلایل زیر استفاده از Sequence بهتر میباشد:
- ممکن است Application شما قبل از درج رکورد، درون یک جدول نیاز به عدد منحصربفردی داشته باشد.
- عدد تولید شده بوسیله Sequence را میتوانید بین جداول یا ستونهای مختلف یک جدول به اشتراک بگذارید.
- میتوانید روند تولید اعداد ترتیبی را Restart نمایید. به عبارت دیگر قابلیت Restart نمودن Sequence وجود دارد.
- میتوانید Sequence خود را براساس Sort یک یا چند فیلد، تنظیم نمایید.
Syntax آن به شرح ذیل میباشد:
CREATE SEQUENCE [schema_name . ] sequence_name [ AS [ built_in_integer_type | user-defined_integer_type ] ] [ START WITH <constant> ] [ INCREMENT BY <constant> ] [ { MINVALUE [ <constant> ] } | { NO MINVALUE } ] [ { MAXVALUE [ <constant> ] } | { NO MAXVALUE } ] [ CYCLE | { NO CYCLE } ] [ { CACHE [ <constant> ] } | { NO CACHE } ] [ ; ]
شرح Syntax :
- در زمان ایجاد Sequence، نوع آن میبایست عددی باشد، چنانچه ،Type آن را مشخص ننمایید، SQL Server، نوع آن را bigint در نظر میگیرد.
- Start With: بدین مفهوم میباشد، که Sequence ایجاد شده از چه عددی آغاز شود.
- INCREMENT BY: مفهومش این است که Sequence به چه مقداری افزایش یا کاهش یابد. به عبارت دیگری عدد تولید شده براساس مقدار Increment by تولید میشود.
- Minvalue: کمترین مقداری که Sequence میتواند ایجاد نماید.
- Maxvalue :بیشترین مقداری که Sequence میتواند ایجاد نماید.
- Cycle :مقداری را که برای Cycle تعیین مینماییم، بدین مفهوم است که Sequence پس از چه عددی میبایست Restart شود.
- Cache :عددی که برای Cache در نظر میگیریم، مفهومش این است که چه تعداد از اعداد تولید شده توسط Sequence، قبل از استفاده، میتواند در Cache قرار گیرد.
در ادامه با یک مثال ساده، یک Sequence ایجاد مینماییم:
CREATE SEQUENCE [dbo].[SequenceTest] AS [int] START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 30 CYCLE CACHE GO
برای اینکه بتوانیم مقدار Sequence را بدست آوریم، کافیست از Syntax زیر استفاده نمایید:
NEXT VALUE FOR [ database_name . ] [ schema_name . ] sequence_name [ OVER (<over_order_by_clause>) ]
اگر Select بالا را تا 30 بار انجام دهید، برای دفعه 31 مقدار آن یک میشود، چون در زمان تعریف Cycle ،Sequence را انتخاب کرده بودیم. در غیر اینصورت برای دفعه 31 با خطا زیر مواجه میشوید.
Msg 11728, Level 16, State 1, Line 1 The sequence object 'SequenceTest' has reached its minimum or maximum value. Restart the sequence object to allow new values to be generated.
در ابتدا مطابق Script زیر جدولی را ایجاد و مقادیری را درون آن درج مینماییم:
create table Kids ( ID int, Name varchar(50) ); Go insert Kids values (1,'Emma') , (1,'Tabitha') , (2,'Kendall') , (3,'Delaney') , (4,'Kyle') , (5,'Jessica') , (6,'Josh') , (7,'Kirsten') , (8,'Amanda') , (9,'Jimmy') ;
CREATE SCHEMA Samples ; GO
CREATE SEQUENCE Samples.Test AS tinyint START WITH 1 INCREMENT BY 1 ; GO
SELECT NEXT VALUE FOR Samples.Test OVER (ORDER BY Name) AS NutID, ID, Name FROM test1.Kids WHERE Name LIKE '%e%' ;
امیدوارم مطلب فوق مفید واقع شده باشد.
اشتراکها
نگارش نهایی SQL Server 2022 منتشر شد
Today, we announced the general availability of SQL Server 2022, the most Azure-enabled release of SQL Server yet, with continued innovation across performance, security, and availability1. This marks the latest milestone in the more than 30-year history of SQL Server.
سلام
Syntax ارائه شده Over Clause در SQL Server 2008 شامل دو پارامتر است :
Ranking Window Functions < OVER_CLAUSE > :: = OVER ( [ PARTITION BY value_expression , ... [ n ] ] <ORDER BY_Clause> ) Aggregate Window Functions < OVER_CLAUSE > :: = OVER ( [ PARTITION BY value_expression , ... [ n ] ] )
در SQL Server 2012 پارامتر <ROW or RANGE clause> به Syntax فوق افزوده شد. بنابراین، Query هایی که از Row یا Range استفاده کرده اند، در SQL Server 2008 با خطا مواجه میشوند.
اشتراکها
پیش نمایش SSMS 18.0 منتشر شد
اشتراکها