سیستم عامل غالب مشتریهای شما کدام است؟
ویندوز 7
ویندوز 8
ویندوز 10
ویندوز سرور 2003
ویندوز سرور 2008
ویندوز سرور 2012
لینوکس
مک
ORDER BY order_by_expression [ COLLATE collation_name ] [ ASC | DESC ] [ ,...n ] [ <offset_fetch> ] <offset_fetch> ::= { OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS } [ FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY ] }
Create Table Testoffset (BusinessEntityID int, FirstName varchar(100) , LastName varchar(100) ); Insert into Testoffset (BusinessEntityID,FirstName,LastName) Values(1,'Ken','Sánchez') ,(2,'Terri','Duffy') ,(3,'Roberto','Tamburello') ,(4,'Rob','Walters') ,(5,'Gail','Erickson') ,(6,'Jossef','Goldberg') ,(7,'Dylan','Miller') ,(8,'Diane','Margheim') ,(9,'Gigi','Matthew') ,(10,'Michael','Raheem')
SELECT BusinessEntityID, FirstName, LastName FROM Testoffset ORDER BY BusinessEntityID OFFSET 3 ROWS FETCH First 3 ROWS only
OpenCVSharp #11
الگوریتم k-Means clustering را میتوان به کمک یک مثال بهتر بررسی کرد. فرض کنید شرکت منسوجاتی قرار است پیراهنهای جدیدی را به بازار ارائه کند. بدیهی است برای فروش بیشتر، بهتر است پیراهنهایی را با اندازههای متفاوتی تولید کرد تا برای عموم مردم مفید باشد. اما ... برای این شرکت مقرون به صرفه نیست تا برای تمام اندازههای ممکن، پیراهن تولید کند. بنابراین اندازههای اشخاص را در سه گروه کوچک، متوسط و بزرگ تعریف میکند. این گروه بندی را میتوان توسط الگوریتم k-means clustering نیز انجام داد و به کمک آن به سه اندازهی بسیار مناسب رسید تا برای عموم اشخاص مناسب باشد. حتی اگر این سه گروه ناکافی باشند، این الگوریتم میتواند تعداد خوشه بندیهای متغیری را دریافت کند تا بهینهترین پاسخ حاصل شود. [برای مطالعه بیشتر]
ارتباط الگوریتم k-means clustering با مباحث پردازش تصویر، در پیش پردازشهای لازمی است که جهت سرفصلهایی مانند تشخیص اشیاء، آنالیز صحنه، ردیابی و امثال آن ضروری هستند. از الگوریتم خوشه بندی k-means عموما جهت مفهومی به نام Color Quantization یا کاهش تعداد رنگهای تصویر استفاده میشود. یکی از مهمترین مزایای این کار، کاهش فشار حافظه و همچنین بالا رفتن سرعت پردازشهای بعدی بر روی تصویر است. همچنین گاهی از اوقات برای چاپ پوسترها نیاز است تعداد رنگهای تصویر را کاهش داد که در اینجا نیز میتوان از این الگوریتم استفاده کرد.
پیاده سازی الگوریتم خوشه بندی K-means
در ادامه کدهای بکارگیری متد kmeans کتابخانهی OpenCV را به کمک OpenCVSharp مشاهده میکنید:
var src = new Mat(@"..\..\Images\fruits.jpg", LoadMode.AnyDepth | LoadMode.AnyColor); Cv2.ImShow("Source", src); Cv2.WaitKey(1); // do events Cv2.Blur(src, src, new Size(15, 15)); Cv2.ImShow("Blurred Image", src); Cv2.WaitKey(1); // do events // Converts the MxNx3 image into a Kx3 matrix where K=MxN and // each row is now a vector in the 3-D space of RGB. // change to a Mx3 column vector (M is number of pixels in image) var columnVector = src.Reshape(cn: 3, rows: src.Rows * src.Cols); // convert to floating point, it is a requirement of the k-means method of OpenCV. var samples = new Mat(); columnVector.ConvertTo(samples, MatType.CV_32FC3); for (var clustersCount = 2; clustersCount <= 8; clustersCount += 2) { var bestLabels = new Mat(); var centers = new Mat(); Cv2.Kmeans( data: samples, k: clustersCount, bestLabels: bestLabels, criteria: new TermCriteria(type: CriteriaType.Epsilon | CriteriaType.Iteration, maxCount: 10, epsilon: 1.0), attempts: 3, flags: KMeansFlag.PpCenters, centers: centers); var clusteredImage = new Mat(src.Rows, src.Cols, src.Type()); for (var size = 0; size < src.Cols * src.Rows; size++) { var clusterIndex = bestLabels.At<int>(0, size); var newPixel = new Vec3b { Item0 = (byte)(centers.At<float>(clusterIndex, 0)), // B Item1 = (byte)(centers.At<float>(clusterIndex, 1)), // G Item2 = (byte)(centers.At<float>(clusterIndex, 2)) // R }; clusteredImage.Set(size / src.Cols, size % src.Cols, newPixel); } Cv2.ImShow(string.Format("Clustered Image [k:{0}]", clustersCount), clusteredImage); Cv2.WaitKey(1); // do events } Cv2.WaitKey(); Cv2.DestroyAllWindows();
توضیحات
- ابتدا تصویر اصلی برنامه بارگذاری میشود و در یک پنجره نمایش داده خواهد شد. در اینجا متد Cv2.WaitKey را با پارامتر یک، مشاهده میکنید. این فراخوانی ویژه، شبیه به متد do events در برنامههای WinForms است. اگر فراخوانی نشود، تمام تصاویر پنجرههای مختلف برنامه تا زمان پایان پردازشهای مختلف برنامه، نمایش داده نخواهند شد و تا آن زمان صرفا یک یا چند پنجرهی خاکستری رنگ را مشاهده خواهید کرد.
- در ادامه متد Blur بر روی این تصویر فراخوانی شدهاست تا مقداری تصویر را مات کند. هدف از بکارگیری این متد در این مثال، برجسته کردن خوشه بندی گروههای رنگی مختلف در تصویر اصلی است.
- سپس متد Reshape بر روی ماتریس تصویر اصلی بارگذاری شده فراخوانی میشود.
هدف از بکارگیری الگوریتم k-means، انتساب برچسبهایی به هر نقطهی RGB تصویر است. در اینجا هر نقطه به شکل یک بردار در فضای سه بعدی مشاهده میشود. سپس سعی خواهد شد تا این MxN بردار، به k قسمت تقسیم شوند.
متد Reshape تصویر اصلی MxNx3 را به یک ماتریس Kx3 تبدیل میکند که در آن K=MxN است و اکنون هر ردیف آن برداری است در فضای سه بعدی RGB.
- پس از آن توسط متد ConvertTo، نوع دادههای این ماتریس جدید به float تبدیل میشوند تا در متد kmeans قابل استفاده شوند.
- در ادامه یک حلقه را مشاهده میکنید که عملیات کاهش رنگهای تصویر و خوشه بندی آنها را 4 بار با مقادیر مختلف clustersCount انجام میدهد.
- در متد kmeans، پارامتر data یک ماتریس float است که هر نمونهی آن در یک ردیف قرار گرفتهاست. K بیانگر تعداد خوشهها، جهت تقسیم دادهها است.
در اینجا پارامترهای labels و centers خروجیهای متد هستند. برچسبها بیانگر اندیسهای هر خوشه به ازای هر نمونه هستند. Centers ماتریس مراکز هر خوشه است و دارای یک ردیف به ازای هر خوشه است.
پارامتر criteria آن مشخص میکند که الگوریتم چگونه باید خاتمه یابد که در آن حداکثر تعداد بررسیها و یا دقت مورد نظر مشخص میشوند.
پارامتر attempts مشخص میکند که این الگوریتم چندبار باید اجرا شود تا بهترین میزان فشردگی و کاهش رنگ حاصل شود.
- پس از پایان عملیات k-means نیاز است تا اطلاعات آن مجددا به شکل ماتریسی هم اندازهی تصویر اصلی برگردانده شود تا بتوان آنرا نمایش داد. در اینجا بهتر میتوان نحوهی عملکرد متد k-means را درک کرد. حلقهی تشکیل شده به اندازهی تمام نقاط طول و عرض تصویر اصلی است. به ازای هر نقطه، توسط الگوریتم k-means یک برچسب تشکیل شده (bestLabels) که مشخص میکند این نقطه متعلق به کدام خوشه و cluster رنگهای کاهش یافته است. سپس بر اساس این اندیس میتوان رنگ این نقطه را از خروجی centers یافته و در یک تصویر جدید نمایش داد.
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید.
IE8 and Below
body { color: red; /* all browsers, of course */ color : green\9; /* IE8 and below */ }
IE7 and Below
body { color: red; /* all browsers, of course */ color : green\9; /* IE8 and below */ *color : yellow; /* IE7 and below */ }
IE6
body { color: red; /* all browsers, of course */ color : green\9; /* IE8 and below */ *color : yellow; /* IE7 and below */ _color : orange; /* IE6 */ }
خواندنیهای 24 خرداد
Silverlight و WPF
دات نت فریم ورک
اس کیوال سرور
متفرقه
بررسی برخی تغییرات در Angular 8
@ViewChild(‘input1’) demoInput:ElementRef; getValueOfElement(){ Console.log(this.demoInput.nativeElement.value); }
@ViewChild(‘input1’,{ static : false }) demoInput:ElementRef; getValueOfElement(){ Console.log(this.demoInput.nativeElement.value); }
در یک نمودار یا چارت سازمانی در حد امکان شاخهها همواره در کنار هم و جمع و جور رسم میشوند. در مثال زیر نود u-Node 1 و u-Node 3 دارای زیر شاخه نبوده ، بنابراین نیازی به فضای زیرین جهت نمایش ندارند. جهت مشاهده این فضا میتوانید خط مشخص شده در کد را فعال نمائید و تفاوت فضای مورد نیاز و ایجاد شده را ببینید.
دو درخت نمودار متفاوت در کنار هم رسم شده اند. هیچ همپوشانی بین درختان رسم شده وجود ندارد ( بنابراین نود Root 2 روی نود u-Node 3 رسم نشده است.
var o = new orgChart(); o.addNode( 0, '', '', 'Root 1'); o.addNode( 1, 0, 'u', 'u-Node 1'); o.addNode( 2, 0, 'u', 'u-Node 2'); o.addNode( 3, 0, 'u', 'u-Node 3'); o.addNode( 4, 0, 'u', 'u-Node 4');
//میتوانید خط زیر را فعال نمائید تا تفاوت فضای ایجاد شده و مورد نیاز را مشاهده نمائید.
//o.addNode( 9, 3, 'u', 'EXTRA', 0, '', '#CC0000', '#FF0000'); o.addNode(11, 2, 'l', 'l-Node'); o.addNode(12, 2, 'u', 'u-Node'); o.addNode(13, 2, 'u', 'u-Node'); o.addNode(14, 2, 'r', 'r-Node'); o.addNode(20, 4, 'l', 'l-Node'); o.addNode(21, '', '', 'Root 2'); o.drawChart('c_layout');
نمونه زیر یک مثال کامل میباشد. انواع اتصالهای تو در تو چندگانه در این نمونه استفاده شده است .
این هم کد نمونه فوق :
var o = new orgChart(); o.setFont('Arial', 18); o.addNode( 0, '', '', 'President', 1); o.setFont('Arial', 12); o.addNode('', 0, 'l', 'Control'); o.addNode('', 0, 'l', 'Secretary'); o.addNode('', 0, 'l', 'Marketing'); o.addNode('', 0, 'l', 'Human resources'); o.setColor('#99CC99', '#CCFFCC'); o.addNode(12, 0, 'r', 'Facility'); o.addNode('', 12, 'r', 'IT'); o.addNode('', 12, 'r', 'Resource planning'); o.setFont('Arial', 18); o.setColor('#CCCC66', '#FFFF99'); o.addNode(20, 0, 'u', 'Projects', 1); o.setFont('Arial', 12); o.addNode('', 20, 'r', 'Management'); o.addNode('', 20, 'r', 'Finance'); o.addNode('', 20, 'l', 'Development'); o.addNode('', 20, 'l', 'Maintenance'); o.addNode('', 20, 'l', 'Specials'); o.setColor('#CC4950', '#FF7C80'); o.setFont('Arial', 18); o.addNode(30, 0, 'u', 'Specials', 1); o.setFont('Arial', 12); o.addNode(31, 30, 'l', 'Management'); o.addNode('', 30, 'l', 'Communication'); o.addNode(33, 30, 'r', 'Development'); o.addNode(34, 33, 'r', 'Maintenance'); o.addNode('', 33, 'r', 'Special A'); o.addNode('', 33, 'r', 'Special B'); o.addNode('', 33, 'r', 'Advice'); o.addNode('', 30, 'l', 'Taskforce'); o.setColor('#CC9966', '#FFCC99'); o.setFont('Arial', 18); o.addNode(40, 0, 'u', 'Programming', 1); o.setFont('Arial', 12); o.addNode(41, 40, 'l', 'Management'); o.addNode(42, 40, 'l', 'Finance'); o.addNode('', 40, 'r', 'Assessment'); o.addNode('', 40, 'r', 'Coding team'); o.addNode('', 40, 'r', 'Quality control'); o.drawChart('c_ex1', '', true);
شما میتوانید به نودها تصویر دلخواه خود را نیز اضافه نمائید. تصاویر بصورت عمودی قرار خواهند گرفت و در صورتی که بزرگ باشند تغییر اندازه خواهند داد. ( فراخوانی تابع setSize قبل از اضافه کردن عکس در این مثال )
کدهای مثال فوق :
var o = new orgChart(); o.setSize(120, 60); o.setFont('Arial', 18); o.addNode( 1, '', '', 'Icon smiley', 0, '', '', '', '', 'pic/smiley.gif'); o.addNode( 2, '', '', 'This is a tree', 0, '', '', '', '', 'pic/tree.jpg'); o.addNode( 3, 2, 'u', 'This is a tree'); o.addNode( 4, '', '', 'Right Top smiley', 0, '', '', '', '', 'pic/smiley.gif', 'rt'); o.addNode( 5, '', '', 'Center bottom smiley', 0, '', '', '', '', 'pic/smiley.gif', 'cb'); o.drawChart('c_img');
یک مثال دیگر از استفاده تصاویر در چارت :
var o = new orgChart(); o.setSize(60, 110); o.setFont('Arial', 12); o.addNode( 1, '', '', 'Hominidae'); o.addNode( 10, 1, 'l', 'Hominidae'); o.addNode( 11, 10, 'l', 'Hominini'); o.addNode( 12, 10, 'r', 'Gorillini'); o.addNode( 20, 1, 'r', 'Ponginae'); o.addNode( '', 11, '', 'Homo Sapiens', '', '', '', '', '', 'pic/homo.jpg', 'ct'); o.addNode( '', 11, '', 'Pan', '', '', '', '', '', 'pic/pan.jpg', 'ct'); o.addNode( '', 12, '', 'Gorilla', '', '', '', '', '', 'pic/gorilla.jpg', 'ct'); o.addNode( '', 20, '', 'Pongo', '', '', '', '', '', 'pic/pongo.jpg', 'ct'); o.drawChart('c_img2', 'c');
عدم امکان استفاده از مرورگر IE تا نسخه 8 ، چرا که IE هیچ پشتیبانی از toDataURL در excanvas.js را انجام نمیدهد.
شما میتوانید از توابع استاندارد canvas در جهت تبدیل محتویات canvas به تصویر استاتیک استفاده نمائید. برای اینکه بتوانید این کار را تست نمائید باید کد ذیل را در همان صفحه ای که کد ( یک مثال کامل ) را استفاده کردید درج نمائید و در این صورت با کلیک بر روی لینک اول میتوانید یک تصویر با فرمت png در یک صفحه جدید از نمودار خود بدست بیاورید و یا با کلیک بر روی لینک دوم یک تصویر را دانلود نمائید.
<script type="text/javascript"> function openAsPng(id){ window.open(document.getElementById(id).toDataURL("image/png")); } function saveAsPng(id){ var img = document.getElementById(id).toDataURL("image/png"); document.location.href = img.replace("image/png", "image/octet-stream"); } </script> <a href = "javascript:openAsPng('c_ex1');">Click here to open the image as png in a new window</a><BR> <a href = "javascript:saveAsPng('c_ex1');">Click here to save the image as png</a><BR>
نمایش چارت فقط بصورت یک تصویر :
برای اینکه بتوانید یک چارت ایجاد شده از این روش را فقط بصورت یک تصویر نمایش دهید باید عمل تبدیل به عکس را بلافاصله پس از رسم نمودار در canvas انجام دهید بدین صورت که در کد ذیل مشاهده مینمائید:
<canvas id="c_pngchart" width="1" height="1">Your browser does not support canvas!</canvas> <img id="pngchart"> <script type="text/javascript"> var o = new orgChart(); o.addNode(0, '', '', 'Root'); o.addNode(1, 0, 'u', 'u-Node 1'); o.addNode(2, 0, 'u', 'u-Node 2'); o.drawChart('c_pngchart', '', true); var canvas = document.getElementById('c_pngchart'); document.getElementById("pngchart").src = canvas.toDataURL("image/png"); // The html keyword "hidden" doesn't work in IE, so resize the canvas to NUL canvas.height = 0; canvas.width = 0; </script>
همه لینکهایی که در نودها ایجاد شده است غیرفعال شده و از کار میافتند. بنابراین برای انجام این کار ،یک المنت تصویر در صفحه خود ایجاد ، نمودار را در canvas رسم نموده ، نمودار را به تصویر تبدیل نموده و آن را به المنت تصویر مقید میکنیم و در آخر canvas مخفی میکنیم. برای این منظور از کلید واژه hidden استفاده میکنیم که در IE این کلمه باز قابل شناسایی نبوده و باید از روش تخصیص اندازه طول و عرض صفر 0 استفاده شود یعنی width=0 , height=0
تصویر فوق ایجاد شده کد مورد نظر میباشد.
تغییر اندازه پویا :
اگر بخواهید بصورت پویا اندازه canvas را تغییر دهید ، نمودار شما ناپدید میشود و پس از تغییر اندازه ، نمودار پاک خواهد شد.
برای رسم نمودار باید دوباره از توابع drawChart() یا redrawChart() استفاده نمائید.
برای رسم نودها نیازی به تعریف دوباره آنها نمیباشد ( مخصوصا در مثالی که در این صفحه برای شما ارائه شده است )
تابع ()drowChart تمامی نودها را در زمان رسم دوباره جاگذاری میکند ، در صورتی که اگر شما میدانید چارت شما به غیر از اندازه هیچ تغییر دیگری نداشته میتوانید با فراخوانی تابع redrawChart یک کپی از همان چارت را که در حافظه canvas وجود دارد را رسم نمائید.
از تمامی دوستان خوبم تشکر میکنم که این مطلب را دنبال نمودند . ما را از نظرات خوب و سازنده خود بی نصیب نفرمائید.
مشکل مهم نوع دادهای int جهت ذخیره سازی مقادیر پولی
فرض کنید جدول سادهای را با دو فیلد Id و Price دارید که نوع مبلغ آنرا با توجه به عدم داشتن خرده در واحد پولی، int انتخاب کردهاید:
CREATE TABLE [Test1]( [Id] [int] IDENTITY(1,1) NOT NULL, [Price] [int] NOT NULL, CONSTRAINT [PK_Test1] PRIMARY KEY CLUSTERED ( [Id] ASC ));
Insert into Test1 values (1000000000),(1000000000),(1000000000),(1000000000),(1000000000),(1000000000),(1000000000)
select sum(price) from Test1
Arithmetic overflow error converting expression to data type int.
برای حل این مشکل میتوان به صورت موقت، نوع دادهای را به bigint تبدیل کرد و مجددا جمع رکوردها را محاسبه کرد:
select sum(cast(price as bigint)) from Test1
از نوع دادهای float برای ذخیره سازی مقادیر پولی استفاده نکنید!
هیچگاه نباید از نوع دادهی float برای ذخیره سازی مقادیر پولی استفاده کرد؛ از این جهت که این نوع اعداد، به صورت تقریبی از یک مقدار decimal و به صورت باینری در SQL Server ذخیره میشوند. به همین جهت به محض ذخیره شدن، با عددی غیر دقیق مواجه خواهیم بود. همچنین مقایسهی دقیق این نوع اعداد هم مشکلات خاصی را به همراه دارد.
DECLARE @f AS FLOAT = '29545428.0211111'; SELECT CAST(@f AS NUMERIC(28, 14)) AS value;
SQL Server چگونه مقادیر پولی money و small money را ذخیره میکند؟
SQL Server برای کار با مقادیر پولی، دو نوع MONEY و SMALLMONEY را ارائه میدهد که شبیه به نوعهای BIGINT و INT، نیاز به 8 و 4 بایت برای ذخیره سازی دارند. در عمل نوع MONEY شبیه به نوع DECIMAL(19,4) و نوع SMALLMONEY همانند DECIMAL(10,4) رفتار میکند. یعنی نوع MONEY میتواند تا 15 رقم دسیمال پیش از ممیز و 4 رقم اعشار را ذخیره کند و نوع SMALLMONEY تنها میتواند 6 رقم دسیمال و 4 رقم اعشاری را ذخیره کند.
اما ... هرچند نوع دادهی MONEY و DECIMAL(19,4) به ظاهر یکی هستند، اما به نحو متفاوتی بر روی دیسک سخت ذخیره میشوند. برای نمونه فرض کنید که قصد داریم عدد 4,513.19 را یکبار به صورت MONEY و بار دیگر به صورت SMALLMONEY ذخیره کنیم که در نهایت به جدول زیر میرسیم:
همانطور که مشاهده میکنید، نوعهای MONEY و SMALLMONEY، دقیقا همانند BIGINT هشت بایتی و INT، چهار بایتی ذخیره میشوند و عملا در پشت صحنهی SQL Server، اعداد صحیح هستند. اما نوع DECIMAL(19,4) که هرچند شبیه به MONEY عمل میکند، 9 بایتی است.
الگوریتم انتخاب نوع دادهی مناسب ذخیره سازی مقادیر پولی
در فلوچارت زیر که از کتاب «Donald Knuth’s "The Art of Computer Programming – Volume 1".» انتخاب شده، روش مواجه شدن با انواع و اقسام نوعهای دادهای عددی را به خوبی مشخص میکند که آیا عدد در حال ذخیره شدن، خرده دارد یا خیر؟ آیا از 922,337,203,685,477.5807 کوچکتر است یا خیر و امثال آن که در تصمیمگیری نهایی مؤثر هستند:
اعدادی را که در این نمودار مشاهده میکنید، در جدول زیر بهتر توضیح داده شدهاند. به عبارتی چه تفاوتی بین نوع Money و Decimal(19,4) مشابه وجود دارد:
تفاوت مهم نوع Money و Decimal(19,4)، در دقت آنها است
تا اینجا به نظر آنچنان تفاوتی بین نوع Money و Decimal(19,4) وجود ندارد و نوع money اتفاقا یک بایت را کمتر اشغال میکند و کوچکتر است. اما تفاوت اصلی را با مثال زیر بهتر میتوان توضیح داد:
CREATE TABLE MoneyTest ( Mon1 money, Mon2 AS Mon1*Mon1, Mon3 AS Mon1*Mon1*Mon1, Dec1 decimal(19,4), Dec2 AS Dec1*Dec1, Dec3 AS Dec1*Dec1*Dec1, MonDec AS Mon1*Dec1, DecMon AS Dec1*Mon1);
همانطور که مشاهده میکنید، با ضرب دو عدد دسیمال، مقادیر پیش و پس از ممیز، یعنی precision و scale تغییر کردهاند، اما در مورد money چنین چیزی رخ نداده و ثابت است. برای مثال زمانیکه با یک عدد DECIMAL(4,2) کار میکنیم، اگر آنرا ضربدر همین عدد کنیم، به یک عدد DECIMAL(8,4) خواهیم رسید که البته حداکثر precision ممکن آن در SQL Server عدد 38 است، اما یک چنین تغییری در حین ضرب اعداد از نوع money رخ نمیدهد.
موضوع دقت را با مثال زیر بهتر میتوان بررسی کرد:
CREATE TABLE [MoneyTest]( [Id] [int] IDENTITY(1,1) NOT NULL, decimalMoney decimal(19,4), moneyMoney money CONSTRAINT [PK_MoneyTest] PRIMARY KEY CLUSTERED ( [Id] ASC ));
INSERT INTO MoneyTest VALUES (12321423442.3456,12321423442.3456), (1111111.1919,1111111.1919)
SELECT * FROM MoneyTest SELECT SUM(decimalMoney) AS [sumDecimal], SUM(moneyMoney) AS [sumMoney] FROM MoneyTest
همانطور که مشخص است در حین محاسباتی مانند جمع و منها و محاسبهی sum، تفاوتی بین این نوعها نیست. اما اگر سعی در تقسیم آنها کنیم:
DECLARE @moneyPer money, @decimalPer decimal(19,4) SET @moneyPer = (SELECT moneyMoney FROM MoneyTest WHERE id = 2)/((SELECT moneyMoney FROM MoneyTest WHERE id = 1)) SET @decimalPer = (SELECT decimalMoney FROM MoneyTest WHERE id = 2)/((SELECT decimalMoney FROM MoneyTest WHERE id = 1)) SELECT @moneyPer AS[moneyPer], @decimalPer AS [decimalPer];
نتیجهی واقعی 0,00009 است که پس از گرد شدن، به 0.0001 مقدار دسیمال میرسیم، اما این دقت در نوع money از دست رفتهاست.
نکتهی مهمی که در اینجا قابل مشاهدهاست، محدود نبودن نتیجهی حاصل، به دقت اعشارها در عدد decimal تعریف شده و scale تعریف شدهی اولیهی آن است. نمونهی دیگر آنرا در مثال زیر میتوانید مشاهده کنید که هرچند عدد دسیمال تعریف شده، فقط 2 رقم اعشاری دارد، اما در حین تقسیم، از این مساله صرفنظر شده و خروجی آن محدود به 2 رقم اعشار نیست؛ برخلاف نوع money که حداکثر 4 رقم ثابت اعشاری را بیشتر نمیتواند داشته باشد:
DECLARE @M MONEY = 1234, @D DECIMAL(6,2) = 1234 SELECT @M/$1000000 AS [MONEY] , @D/$1000000 AS [DECIMAL]
نتیجهگیری
برای ذخیره سازی مقادیر پولی در SQL Server، اگر سیستم شما OLTP-like است و با اعدادی مانند 1000.24 کار میکنید و حداکثر میخواهید جمع و منهای آنها را محاسبه کنید، انتخاب نوع MONEY و یا SMALLMONEY بسیار مناسب است؛ اما اگر سیستم شما OLAP-like است و در آن اعمال ضرب و تقسیم زیاد رخ میدهد، فقط از نوع Decimal استفاده کنید.
DECLARE @dOne DECIMAL(19,4) = 1, @dThree DECIMAL(19,4) = 3, @mOne MONEY = 1, @mThree MONEY = 3 SELECT (@dOne/@dThree) * @dThree AS DecimalResult, (@mOne/@mThree) * @mThree AS MoneyResult
برای ادامه دادن این سری از مقالات آموزش MDX Query نیاز میباشد که پایگاه دادهی Advwnture Work DW را نصب کرده و سپس توسط SSAS عمل Deploy را انجام دهیم تا پایگاه دادهی Multidimensional Database توسط SSAS ساخته شود .
در ابتدا میبایست فایل نصب پایگاه داده ی Advwnture Work را دانلود نمایید برای این منظور به آدرس زیر رفته و فایل AdventureWorks2008R2_SR1.exe را دانلود نمایید .
http://www.general-files.biz/download/gs4ac37d18h17i0/AdventureWorks2008R2_SR1.exe.html
یا به آدرس زیر مراجعه کنید
https://msftdbprodsamples.codeplex.com/releases/view/59211
نیاز میباشد قبل از شروع به نصب نرم افزار SQL Server Management Studio را ببندید.
سپس مراحل زیر را انجام دهید.
1. فایل AdventureWorks2008R2_SR1.exe را اجرا نمایید.
2. کمی صبر کنید تا صفحهی زیر نمایش داده شود. و گزینهی I Accept … را انتخاب نماید و دکمهی Next را بزنید.
3. در صورتی که از ویندوز 8 استفاده نماید احتمال دارد با خطای زیر مواجه شوید در این صورت به قسمت روش نصب در ویندوز 8 در ادامهی این مقاله مراجعه کنید .
4. در صورتی که از ویندوزهای Server 2003, XP , Win7 استفاده کنید صفحهی زیر را خواهید دید. در این صفحه ابتدا Instance مربوط به SQL سرور خود را انتخاب نماید (در صورت داشتن چندین Instance روی سرور پایگاه داده) سپس مسیر نصب فایلهای Sample را مشخص نمایید (بعدا از همین مسیر اقدام به Deploy کردن پایگاه دادهی Multidimensional خواهیم کرد) و پیش فرضها را بپذیرید و دکمهی Install را بزنید.
5. کمی صبر کنید تا نصب انجام گردد. و در انتها کلید Finish را بزنید.
پس از مراحل بالا (به جز ویندوز 8) با باز کردن نرم افزار SQL Server Management Studio و اتصال به سرویس Database Engine در قسمت Database تصویر زیر را خواهید دید (البته امکان دارد شما از قبل دارای پایگاه دادههای شخصی بوده باشید که بنابر این آنها نیز در لیست شما وجود خواهند داشت)
همچنین شما میتوانید از پنجرهی Object Explorer در قسمت Connect اقدام به اتصال به سرویس SSAS نموده .
و در پنجرهی باز شده Server Name را انتخاب نمایید (با توجه به اینکه شما در حال حاضر میخواهید به SSAS موجود در سیستم Local متصل شوید ، بنابر این انتخاب سرور Local با وارد کردن کاراکتر (.) انجام میشود.)
بعد از اتصال شکل زیر را خواهید داشت و در شاخهی Database همچنان هیچ Multidimensional Database ی نخواهید داشت.(بعد از عمل Deploy که در ادامه آموزش داده خواهد شد پایگاه دادهی Multidimensional ساخته میشود.)
تنها روشی که تاکنون برای نصب پایگاه دادهی Adventure Work DW برروی ویندوز 8 یافته ام (البته کمی غیر حرفه ای میباشد.) به صورت زیر میباشد.
فایل بالا را ( AdventureWorks2008R2_SR1.exe ) روی سیستم عاملهای ( Server 2003,XP,Win 7 ) نصب کرده (به عنوان یک سیستم عامل واسط) و سپس سرویس Database Engine را Stop کرده و فایلهای پایگاه داده را به سیستم عامل ویندوز 8 انتقال داده و به صورت دستی Restore کنیم.
مراحل ایجاد پایگاه دادهی Multidimensional در ویندوزهای مختلف ، یکسان میباشد.
بعد از نصب پایگاه دادهی Adventure Work DW باید به شاخهی نصب Sample بروید (همان مسیری که در مراحل نصب وارد کردیم و البته آدرس پیش فرض آن C:\Program Files\Microsoft Sql Server\100\Tools\Sample میباشد.)
(در صورتی که در ویندوز 8 مراحل نصب را دنبال میکنید مسیر زیر را در سیستم خود درست نمایید و فایلها و پوشههای موجود در مسیر فوق در سیستم عامل واسط (همان سیستم عاملی که فایل نصب بر روی آن نصب شده است) را به درون آن انتقال دهید.)
سپس به زیر شاخهی \ AdventureWorks 2008R2 Analysis Services Project\enterprise بروید و فایل Adventure Works.sln را با Visual Studio 2010 باز کنید.
احتمال دارد که نیاز باشد روی کل شاخهی enterprise در قسمت Security کاربر جاری را Add کنید و به آن دسترسی Full Control بدهید تا عملیات Convert این پروژه به درستی انجام شود.
پس از باز کردن پروژه در Visual Studio 2010 صفحه ای مطابق تصویر زیر در پنجرهی Solution Explorer خواهید دید.
به هیچ عنوان نگران ساختار این پروژه نباشید ، زیرا در مقالههای آیند شرح کاملی در این خصوص کار با Business Intelligence Management Studio خواهم داد. فعلا هدف ما ایجاد پایگاه دادهی Multidimensional می باشد.
برای ساخت پایگاه دادهی Multidimensional مراحل زیر را دنبال نمایید.
1. در ابتدا روی پروژه کلیک راست کرده و گزینهی Properties را انتخاب نمایید.
2. در قسمت Configuration Properties منوی Deployment را انتخاب کرده و اطمینان حاصل کنید که سرور شما LocalHost و نام پایگاه داده شما Adventure Works DW 2008R2 باشد.
3. سپس روی Adventure Works.ds کلیک راست کنید تا تنظیمات Connection String به DW را انجام دهیم. مطابق شکل زیر
4. سپس در پنجرهی باز شده دکمهی Edit را بزنید .
5. و در صفحه باز شده تنظیمات زیر را مطابق تصویر زیر انجام دهید. دقت داشته باشید که تغییرات را از بالا به پایین باید انجام دهید و قبل از زدن دکمهی OK حتما Test Connection را بزنید تا از صحت تنظیمات مطمعا شوید.
6. سپس دو بار دکمهی OK را در دوصفحه کلیک کنید. (بعد از این مراحل شما آمادهی Deploy کردن میباشد)
7. در ابتدا پروژه را Build نمایید ( CTRl + Shift + B ) و اطمینان حاصل کنید که Build با موفقیت انجام میشود.
8. در انتها برروی نام پروژه کلیک راست نمایید و گزینهی Deploy را انتخاب نمایید. فرایند Deploy کردن میتواند کمی زمان بر باشد بنابر این شکیبا باشید و در انتها پیام Deployment Completed Successfully را دریافت خواهید کرد.
9. حال به SQL Server Management Studio بروید و به سرویس SSAS کانکت شوید . در قسمت DataBase یک پایگاه داده با نام Adventure Works DW 2008R2 مشاهده خواهید کرد .
به شما تبریک میگویم اینک شما یک پایگاه دادهی Multidimensional را ساخته اید .
در مقالهی بعدی توضیحاتی در خصوص BIMS (Business Intelligence Management Studio) خواهم داد و همچنین اولین MDX Query را خواهیم نوشت.