اشتراکها
مطالب
آشنایی با DGML
یکی از قابلیتهای جدید VS2010 ، معرفی یک markup language است به نام DGML که از آن جهت data visualization و رسم انواع و اقسام گرافها استفاده میشود.
چند دموی جالب از آن در این سایت قابل دریافت است (اگر موفق به باز کردن سایت شدید که چقدر هم خوب، اگر نه، mirror این دموها از آدرسهای زیر هم قابل دریافت است):
برخلاف محصولات دهه قبل مایکروسافت، در تعداد زیادی از محصولات جدید سرور آن (خصوصا در کنترل پنلهای تحت وب این محصولات)، استفاده وسیعی از Silverlight مشاهده میشود که لیستی از آنها را در ادامه مشاهده خواهید کرد:
Lync Server 2010 (یا همان communication server قدیم) محصولی است جهت مدیریت ارتباطات پیشرفته: (+)
ویندوز Azure که یکی از محصولات استراتژیک مایکروسافت محسوب میشود: (+)
Windows Intune جهت بررسی و به روز رسانی وضعیت شبکه، سرورها و کامپیوترهای آن بکار میرود: (+)
System Center برای مدیریت سرورهای مایکروسافت کاربرد دارد: (+)
پروژه جدید Crescent از تیم SQL Server جهت data visualization پیشرفته اطلاعات: (+)
در تکمیل مثالهای فوق میتوان به Visual Studio LightSwitch نیز اشاره کرد. هدف اصلی این محصول فراهم آوردن امکان تولید برنامههای بانک اطلاعاتی مبتنی بر سیلورلایت جهت افرادی با تجربهی کمتر برنامه نویسی میباشد: (+)
این نوع محصولات ویژه سرور عموما جهت Windows platform تهیه میشوند و زمانیکه بازهی سیعتری از کاربران مدنظر باشند همانند Office web apps کمتر از Silverlight استفاده شده است و اینجا شاید این سؤال مطرح شود که چرا Silverlight ؟ در این مورد مطلب مفصلی را اینجا میتوانید مطالعه کنید: (+)
اشتراکها
بررسی DataTable
اشتراکها
انتخاب سادهتر رنگهای CSS ایی
مطالب دورهها
متدهای توکار استفاده از نوع دادهای XML - قسمت دوم
امکان ترکیب دادههای یک بانک اطلاعاتی رابطهای و XML در SQL Server به کمک یک سری تابع کمکی خاص به نامهای sql:variable و sql:column پیش بینی شدهاست. sql:variable امکان استفاده از یک متغیر T-SQL را داخل یک XQuery میسر میسازد و توسط sql:column میتوان با یکی از ستونهای ذکر شده در قسمت select، داخل XQuery کار کرد. در ادامه به مثالهایی در این مورد خواهیم پرداخت.
ابتدا جدول xmlTest را به همراه چند رکورد ثبت شده در آن، درنظر بگیرید:
استفاده از متد sql:column
در ادامه میخواهیم مقدار ویژگی name رکوردی را که نام آن Vahid است، به همراه id آن ردیف، توسط یک XQuery بازگشت دهیم:
یک sql:column حتما نیاز به یک نام ستون دو قسمتی دارد. قسمت اول آن نام جدول است و قسمت دوم، نام ستون مورد نظر.
در مورد متد data در قسمت قبل بیشتر بحث شد و از آن برای استخراج دادهی یک ویژگی در اینجا استفاده شدهاست. عبارات داخل {} نیز پویا بوده و به همراه سایر قسمتهای ثابت return، ابتدا محاسبه و سپس بازگشت داده میشود.
اگر این کوئری را اجرا کنید، ردیف اول آن مساوی عبارت زیر خواهد بود
به همراه دو ردیف خالی دیگر در ادامه. این ردیفهای خالی به علت وجود دو رکورد دیگری است که با شرط where یاد شده تطابق ندارند.
یک روش برای حذف این ردیفهای خالی استفاده از متد exist است به شکل زیر:
در اینجا فقط ردیفی انتخاب خواهد شد که نام ویژگی آن Vahid است.
روش دوم استفاده از یک derived table و بازگشت ردیفهای غیرخالی است:
استفاده از متد sql:variable
در این مثال نحوهی بکارگیری یک متغیر T-SQL را داخل یک XQuery توسط متد sql:variable ملاحظه میکنید.
استفاده از For XML برای دریافت یکبارهی تمام ردیفهای XML
اگر کوئری معمولی ذیل را اجرا کنیم:
سه ردیف خروجی را مطابق سه رکوردی که ثبت کردیم، بازگشت میدهد.
اما اگر بخواهیم این سه ردیف را با هم ترکیب کرده و تبدیل به یک نتیجهی واحد کنیم، میتوان از For XML به نحو ذیل استفاده کرد:
بررسی متد xml.nodes
متد xml.nodes اندکی متفاوت است نسبت به تمام متدهایی که تاکنون بررسی کردیم. کار آن تجزیهی محتوای XML ایی به ستونها و سطرها میباشد. بسیار شبیه است به متد OpenXML اما کارآیی بهتری دارد.
در اینجا یک سند XML را درنظر بگیرید که از چندین نود شخص تشکیل شدهاست. اغلب آنها دارای یک name هستند. چهارمین نود، دو نام دارد و آخری بدون نام است.
در ادامه قصد داریم این اطلاعات را تبدیل به ردیفهایی کنیم که هر ردیف حاوی یک نام است. اولین سعی احتمالا استفاده از متد value خواهد بود:
این روش کار نمیکند زیرا متد value، بیش از یک مقدار را نمیتواند بازگشت دهد. البته میتوان از متد value به نحو زیر استفاده کرد:
اما حاصل آن دقیقا چیزی نیست که دنبالش هستیم؛ ما دقیقا نیاز به تمام نامها داریم و نه تنها یکی از آنها را.
سعی بعدی استفاده از متد query است:
در این حالت تمام نامها را بدست میآوریم:
اما این حاصل دو مشکل را به همراه دارد:
الف) خروجی آن XML است.
ب) تمام اینها در طی یک ردیف و یک ستون بازگشت داده میشوند.
و این خروجی نیز چیزی نیست که برای ما مفید باشد. ما به ازای هر شخص نیاز به یک ردیف جداگانه داریم. اینجا است که متد xml.nodes مفید واقع میشود:
خروجی متد xml.nodes یک table valued function است؛ یک جدول را باز میگرداند که دقیقا حاوی یک ستون میباشد. به همین جهت Alias آنرا با tab col مشخص کردهایم. tab متناظر است با جدول بازگشت داده شده و col متناظر است با تک ستون این جدول حاصل. این نامها در اینجا مهم نیستند؛ اما ذکر آنها اجباری است.
هر ردیف حاصل از این جدول بازگشت داده شده، یک اشارهگر است. به همین جهت نمیتوان آنها را مستقیما نمایش داد. هر سطر آن، به نودی که با آن مطابق XQuery وارد شده تطابق داشته است، اشاره میکند. در اینجا مطابق کوئری نوشته شده، هر ردیف به یک نود name اشاره میکند. در ادامه برای استخراج اطلاعات آن میتوان از متد text استفاده کرد.
اگر قصد داشتید، اطلاعات کامل نود ردیف جاری را مشاهده کنید میتوان از
استفاده کرد. دات در اینجا به معنای self است. دو دات (نقطه) پشت سرهم به معنای درخواست اطلاعات والد نود میباشد.
روش دیگر بدست آوردن مقدار یک نود را در کوئری ذیل مشاهده میکنید؛ value دات و data دات. خروجی value مقدار آن نود است و خروجی data مقدار آن نود با فرمت XML.
همچنین اگر بخواهیم اطلاعات تنها یک نود خاص را بدست بیاوریم، میتوان مانند کوئری ذیل عمل کرد:
در مورد کار با جداول، بجای متغیرهای T-SQL نیز روال کار به همین نحو است:
در اینجا یک جدول حاوی ستون XML ایی ایجاد شدهاست. سپس چهار ردیف در آن ثبت شدهاند. در آخر مقدار ویژگی نام این ردیفها بازگشت داده شدهاست.
نکته : استفادهی وسیع SQL Server از XML برای پردازش کارهای درونی آن
بسیاری از ابزارهایی که در نگارشهای جدید SQL Server اضافه شدهاند و یا مورد استفاده قرار میگیرند، استفادهی وسیعی از امکانات توکار XML آن دارند. مانند:
Showplan، گرافهای dead lock، گزارش پروسههای بلاک شده، اطلاعات رخدادها، SSIS Jobs، رخدادهای Trace و ...
مثال اول: کدام کوئریها در Plan cache، کارآیی پایینی داشته و table scan را انجام میدهند؟
اطلاعات Query Plan در SQL Server با فرمت XML ارائه میشود. در اینجا میخواهیم یک سری متغیر مانند Clustered Index Scan و امثال آنرا از ویژگی PhysicalOp آن کوئری بگیریم. بنابراین از متد sql:variable کمک گرفته شدهاست.
اگر علاقمند هستید که اصل این اطلاعات را با فرمت XML مشاهده کنید، کوئری نوشته شده را تا پیش از where آن یکبار مستقلا اجرا کنید. ستون آخر آن query_plan نام دارد و حاوی اطلاعات XML ایی است.
مثال دوم: استخراج اپراتورهای رابطهای (RelOp) از یک Query Plan ذخیره شده
در اینجا کار کردن با WITH XMLNAMESPACES در حین استفاده از متد xml.nodes سادهتر است؛ بجای قرار دادن فضای نام در تمام کوئریهای نوشته شده.
بررسی متد xml.modify
تا اینجا تمام کارهایی که صورت گرفت و نکاتی که بررسی شدند، به مباحث select اختصاص داشتند. اما insert، delete و یا update قسمتی از یک سند XML بررسی نشدند. برای این منظور باید از متد xml.modify استفاده کرد. از آن در عبارات update و یا set کمک گرفته شده و ورودی آن نباید نال باشد. در ادامه در طی مثالهایی این موارد را بررسی خواهیم کرد.
ابتدا فرض کنید که سند XML ما چنین شکلی را دارا است:
در ادامه قصد داریم یک نود جدید را پس از CustomerName اضافه کنیم.
اینکار را با استفاده از دستور insert، به نحو فوق میتوان انجام داد. از عبارت Set و متغیر doc مقدار دهی شده، کار شروع شده و سپس نود جدیدی پس از (after) اولین نود CustomerName موجود insert میشود. Select بعدی نتیجه را نمایش خواهد داد.
در SQL Server 2008 به بعد، امکان استفاده از متغیرهای T-SQL نیز در اینجا مجاز شدهاست:
بنابراین اگر نیاز به تعریف متغیری در اینجا داشتید از جمع زدن رشتهها استفاده نکنید. حتما نیاز است متغیر تعریف شود و گرنه باخطای ذیل متوقف خواهید شد:
افزودن ویژگیهای جدید به یک سند XML توسط متد xml.modify
اگر بخواهیم یک ویژگی (attribute) جدید را به نود خاصی اضافه کنیم میتوان به نحو ذیل عمل کرد:
که خروجی دو سطر ابتدایی آن پس از اضافه شدن ویژگی status با مقدار backorder به نحو ذیل است:
حذف نودهای یک سند XML توسط متد xml.modify
اگر بخواهیم تمام LineItemها را حذف کنیم میتوان نوشت:
با این خروجی:
به روز رسانی نودهای یک سند XML توسط متد xml.modify
اگر نیاز باشد تا مقدار یک نود را تغییر دهیم میتوان از replace value of استفاده کرد:
با خروجی ذیل که در آن نام اولین مشتری با مقدار Farid جایگزین شده است:
replace value of فقط با یک نود کار میکند و همچنین، فقط مقدار آن نود را تغییر میدهد. به همین جهت از متد text استفاده شدهاست. اگر از text استفاده نشود با خطای ذیل متوقف خواهیم شد:
به روز رسانی نودهای خالی توسط متد xml.modify
باید دقت داشت، نودهای خالی (بدون مقدار)، مانند LineItems پس از delete کلیه اعضای آن در مثال قبل، قابل replace نیستند و باید مقادیر جدید را در آنها insert کرد. یک مثال:
در این مثال اگر از replace value of برای مقدار دهی نود سوم استفاده میشد:
تغییری را پس از اعمال دستورات مشاهده نمیکردید؛ زیرا این المان ()text ایی را برای replace شدن ندارد.
ابتدا جدول xmlTest را به همراه چند رکورد ثبت شده در آن، درنظر بگیرید:
CREATE TABLE xmlTest ( id INT IDENTITY PRIMARY KEY, doc XML ) GO INSERT xmlTest VALUES('<Person name="Vahid" />') INSERT xmlTest VALUES('<Person name="Farid" />') INSERT xmlTest VALUES('<Person name="Mehdi" /><Person name="Hamid" />') GO
استفاده از متد sql:column
در ادامه میخواهیم مقدار ویژگی name رکوردی را که نام آن Vahid است، به همراه id آن ردیف، توسط یک XQuery بازگشت دهیم:
SELECT doc.query(' for $p in //Person where $p/@name="Vahid" return <li>{data($p/@name)} has id = {sql:column("xmlTest.id")}</li> ') FROM xmlTest
در مورد متد data در قسمت قبل بیشتر بحث شد و از آن برای استخراج دادهی یک ویژگی در اینجا استفاده شدهاست. عبارات داخل {} نیز پویا بوده و به همراه سایر قسمتهای ثابت return، ابتدا محاسبه و سپس بازگشت داده میشود.
اگر این کوئری را اجرا کنید، ردیف اول آن مساوی عبارت زیر خواهد بود
<li>Vahid has id = 1</li>
یک روش برای حذف این ردیفهای خالی استفاده از متد exist است به شکل زیر:
SELECT doc.query(' for $p in //Person where $p/@name="Vahid" return <li>{data($p/@name)} has id = {sql:column("xmlTest.id")}</li> ') FROM xmlTest WHERE doc.exist(' for $p in //Person where $p/@name="Vahid" return <li>{data($p/@name)} has id = {sql:column("xmlTest.id")}</li> ')=1
روش دوم استفاده از یک derived table و بازگشت ردیفهای غیرخالی است:
SELECT * FROM ( (SELECT doc.query(' for $p in //Person where $p/@name="Vahid" return <li>{data($p/@name)} has id = {sql:column("xmlTest.id")}</li> ') AS col1 FROM xmlTest) ) A WHERE CONVERT(VARCHAR(8000), col1)<>''
استفاده از متد sql:variable
DECLARE @number INT = 1 SELECT doc.query(' for $p in //Person where $p/@name="Vahid" return <li>{data($p/@name)} has number = {sql:variable("@number")}</li> ') FROM xmlTest
استفاده از For XML برای دریافت یکبارهی تمام ردیفهای XML
اگر کوئری معمولی ذیل را اجرا کنیم:
SELECT doc.query('/Person') FROM xmlTest
اما اگر بخواهیم این سه ردیف را با هم ترکیب کرده و تبدیل به یک نتیجهی واحد کنیم، میتوان از For XML به نحو ذیل استفاده کرد:
DECLARE @doc XML SET @doc = (SELECT * FROM xmlTest FOR XML AUTO, ELEMENTS) SELECT @doc.query('/xmlTest/doc/Person')
بررسی متد xml.nodes
متد xml.nodes اندکی متفاوت است نسبت به تمام متدهایی که تاکنون بررسی کردیم. کار آن تجزیهی محتوای XML ایی به ستونها و سطرها میباشد. بسیار شبیه است به متد OpenXML اما کارآیی بهتری دارد.
DECLARE @doc XML =' <people> <person><name>Vahid</name></person> <person><name id="2">Farid</name></person> <person><name>Mehdi</name></person> <person><name>Hooshang</name><name id="1">Hooshi</name></person> <person></person> </people> '
در ادامه قصد داریم این اطلاعات را تبدیل به ردیفهایی کنیم که هر ردیف حاوی یک نام است. اولین سعی احتمالا استفاده از متد value خواهد بود:
SELECT @doc.value('/people/person/name', 'varchar(50)')
SELECT @doc.value('(/people/person/name)[1]', 'varchar(50)')
سعی بعدی استفاده از متد query است:
SELECT @doc.query('/people/person/name')
<name>Vahid</name> <name id="2">Farid</name> <name>Mehdi</name> <name>Hooshang</name> <name id="1">Hooshi</name>
الف) خروجی آن XML است.
ب) تمام اینها در طی یک ردیف و یک ستون بازگشت داده میشوند.
و این خروجی نیز چیزی نیست که برای ما مفید باشد. ما به ازای هر شخص نیاز به یک ردیف جداگانه داریم. اینجا است که متد xml.nodes مفید واقع میشود:
SELECT tab.col.value('text()[1]', 'varchar(50)') AS name, tab.col.query('.'), tab.col.query('..') from @doc.nodes('/people/person/name') AS tab(col)
هر ردیف حاصل از این جدول بازگشت داده شده، یک اشارهگر است. به همین جهت نمیتوان آنها را مستقیما نمایش داد. هر سطر آن، به نودی که با آن مطابق XQuery وارد شده تطابق داشته است، اشاره میکند. در اینجا مطابق کوئری نوشته شده، هر ردیف به یک نود name اشاره میکند. در ادامه برای استخراج اطلاعات آن میتوان از متد text استفاده کرد.
اگر قصد داشتید، اطلاعات کامل نود ردیف جاری را مشاهده کنید میتوان از
tab.col.query('.'),
روش دیگر بدست آوردن مقدار یک نود را در کوئری ذیل مشاهده میکنید؛ value دات و data دات. خروجی value مقدار آن نود است و خروجی data مقدار آن نود با فرمت XML.
SELECT tab.col.value('.', 'varchar(50)') AS name, tab.col.query('data(.)'), tab.col.query('.'), tab.col.query('..') from @doc.nodes('/people/person/name') AS tab(col)
همچنین اگر بخواهیم اطلاعات تنها یک نود خاص را بدست بیاوریم، میتوان مانند کوئری ذیل عمل کرد:
SELECT tab.col.value('name[.="Farid"][1]', 'varchar(50)') AS name, tab.col.value('name[.="Farid"][1]/@id', 'varchar(50)') AS id, tab.col.query('.') from @doc.nodes('/people/person[name="Farid"]') AS tab(col)
در مورد کار با جداول، بجای متغیرهای T-SQL نیز روال کار به همین نحو است:
DECLARE @tblXML TABLE ( id INT IDENTITY PRIMARY KEY, doc XML ) INSERT @tblXML VALUES('<person name="Vahid" />') INSERT @tblXML VALUES('<person name="Farid" />') INSERT @tblXML VALUES('<person />') INSERT @tblXML VALUES(NULL) SELECT id, doc.value('(/person/@name)[1]', 'varchar(50)') AS name FROM @tblXML
نکته : استفادهی وسیع SQL Server از XML برای پردازش کارهای درونی آن
بسیاری از ابزارهایی که در نگارشهای جدید SQL Server اضافه شدهاند و یا مورد استفاده قرار میگیرند، استفادهی وسیعی از امکانات توکار XML آن دارند. مانند:
Showplan، گرافهای dead lock، گزارش پروسههای بلاک شده، اطلاعات رخدادها، SSIS Jobs، رخدادهای Trace و ...
مثال اول: کدام کوئریها در Plan cache، کارآیی پایینی داشته و table scan را انجام میدهند؟
CREATE PROCEDURE LookForPhysicalOps (@op VARCHAR(30)) AS SELECT sql.text, qs.EXECUTION_COUNT, qs.*, p.* FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(sql_handle) sql CROSS APPLY sys.dm_exec_query_plan(plan_handle) p WHERE query_plan.exist(' declare default element namespace "http://schemas.microsoft.com/sqlserver/2004/07/showplan"; /ShowPlanXML/BatchSequence/Batch/Statements//RelOp/@PhysicalOp[. = sql:variable("@op")] ') = 1 GO EXECUTE LookForPhysicalOps 'Table Scan' EXECUTE LookForPhysicalOps 'Clustered Index Scan' EXECUTE LookForPhysicalOps 'Hash Match'
اگر علاقمند هستید که اصل این اطلاعات را با فرمت XML مشاهده کنید، کوئری نوشته شده را تا پیش از where آن یکبار مستقلا اجرا کنید. ستون آخر آن query_plan نام دارد و حاوی اطلاعات XML ایی است.
مثال دوم: استخراج اپراتورهای رابطهای (RelOp) از یک Query Plan ذخیره شده
WITH XMLNAMESPACES(DEFAULT N'http://schemas.microsoft.com/sqlserver/2004/07/showplan') SELECT RelOp.op.value(N'../../@NodeId', N'int') AS ParentOperationID, RelOp.op.value(N'@NodeId', N'int') AS OperationID, RelOp.op.value(N'@PhysicalOp', N'varchar(50)') AS PhysicalOperator, RelOp.op.value(N'@LogicalOp', N'varchar(50)') AS LogicalOperator, RelOp.op.value(N'@EstimatedTotalSubtreeCost ', N'float') AS EstimatedCost, RelOp.op.value(N'@EstimateIO', N'float') AS EstimatedIO, RelOp.op.value(N'@EstimateCPU', N'float') AS EstimatedCPU, RelOp.op.value(N'@EstimateRows', N'float') AS EstimatedRows, cp.plan_handle AS PlanHandle, st.TEXT AS QueryText, qp.query_plan AS QueryPlan, cp.cacheobjtype AS CacheObjectType, cp.objtype AS ObjectType FROM sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) st CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) qp CROSS APPLY qp.query_plan.nodes(N'//RelOp') RelOp(op)
بررسی متد xml.modify
تا اینجا تمام کارهایی که صورت گرفت و نکاتی که بررسی شدند، به مباحث select اختصاص داشتند. اما insert، delete و یا update قسمتی از یک سند XML بررسی نشدند. برای این منظور باید از متد xml.modify استفاده کرد. از آن در عبارات update و یا set کمک گرفته شده و ورودی آن نباید نال باشد. در ادامه در طی مثالهایی این موارد را بررسی خواهیم کرد.
ابتدا فرض کنید که سند XML ما چنین شکلی را دارا است:
DECLARE @doc XML = ' <Invoice> <InvoiceId>100</InvoiceId> <CustomerName>Vahid</CustomerName> <LineItems> <LineItem> <Sku>134</Sku> <Quantity>10</Quantity> <Description>Item 1</Description> <UnitPrice>9.5</UnitPrice> </LineItem> <LineItem> <Sku>150</Sku> <Quantity>5</Quantity> <Description>Item 2</Description> <UnitPrice>1.5</UnitPrice> </LineItem> </LineItems> </Invoice> '
SET @doc.modify(' insert <InvoiceInfo><InvoiceDate>2014-02-10</InvoiceDate></InvoiceInfo> after /Invoice[1]/CustomerName[1] ') SELECT @doc
<Invoice> <InvoiceId>100</InvoiceId> <CustomerName>Vahid</CustomerName> <InvoiceInfo> <InvoiceDate>2014-02-10</InvoiceDate> </InvoiceInfo> <LineItems> ...
در SQL Server 2008 به بعد، امکان استفاده از متغیرهای T-SQL نیز در اینجا مجاز شدهاست:
SET @x.modify('insert sql:variable("@x") into /doc[1]')
The argument 1 of the XML data type method "modify" must be a string literal.
افزودن ویژگیهای جدید به یک سند XML توسط متد xml.modify
اگر بخواهیم یک ویژگی (attribute) جدید را به نود خاصی اضافه کنیم میتوان به نحو ذیل عمل کرد:
SET @doc.modify(' insert attribute status{"backorder"} into /Invoice[1] ') SELECT @doc
<Invoice status="backorder"> <InvoiceId>100</InvoiceId> ....
حذف نودهای یک سند XML توسط متد xml.modify
اگر بخواهیم تمام LineItemها را حذف کنیم میتوان نوشت:
SET @doc.modify('delete /Invoice/LineItems/LineItem') SELECT @doc
<Invoice status="backorder"> <InvoiceId>100</InvoiceId> <CustomerName>Vahid</CustomerName> <InvoiceInfo> <InvoiceDate>2014-02-10</InvoiceDate> </InvoiceInfo> <LineItems /> </Invoice>
به روز رسانی نودهای یک سند XML توسط متد xml.modify
اگر نیاز باشد تا مقدار یک نود را تغییر دهیم میتوان از replace value of استفاده کرد:
SET @doc.modify('replace value of /Invoice[1]/CustomerName[1]/text()[1] with "Farid" ') SELECT @doc
<Invoice status="backorder"> <InvoiceId>100</InvoiceId> <CustomerName>Farid</CustomerName> <InvoiceInfo> <InvoiceDate>2014-02-10</InvoiceDate> </InvoiceInfo> <LineItems /> </Invoice>
The target of 'replace value of' must be a non-metadata attribute or an element with simple typed content.
به روز رسانی نودهای خالی توسط متد xml.modify
باید دقت داشت، نودهای خالی (بدون مقدار)، مانند LineItems پس از delete کلیه اعضای آن در مثال قبل، قابل replace نیستند و باید مقادیر جدید را در آنها insert کرد. یک مثال:
DECLARE @tblTest AS TABLE (xmlField XML) INSERT INTO @tblTest(xmlField) VALUES ( '<Sample> <Node1>Value1</Node1> <Node2>Value2</Node2> <Node3/> </Sample>' ) DECLARE @newValue VARCHAR(50) = 'NewValue' UPDATE @tblTest SET xmlField.modify( 'insert text{sql:variable("@newValue")} into (/Sample/Node3)[1] [not(text())]' ) SELECT xmlField.value('(/Sample/Node3)[1]','varchar(50)') FROM @tblTest
UPDATE @tblTest SET xmlField.modify( 'replace value of (/Sample/Node3/text())[1] with sql:variable("@newValue")' )
اشتراکها
D3 6.0 منتشر شد
D3 6.0: The Data-Driven Document Library — The popular data visualization library takes a step forward by switching out a few internal dependencies for better alternatives, adopts ES2015 (a.k.a. ES6) internally, and now passes events directly to listeners. There’s also a 5.x to 6.0 migration guide for existing users.
اشتراکها
کتابخانه vizicities
3D city and data visualization platform Demo
Libraries and resources used
- OpenStreetMap – Map data
- Three.js – WebGL
- D3.js – Geographic coordinate conversion
- Underscore.js – General helpers
- Q – Promises
- Throat - Limiting concurrency
- Catiline – Web Workers
- Dat.gui – Debug control panel
- FPSMeter – FPS meter
- Moment.js – Date processing
- Simplify.js – Polygon simplification
- Grunt – Build system
پیشتر مطالبی در سایت، درباره KenoUI و همچنین ویجتهای وب آن منتشر گردید. در این مطلب نگاهی خواهیم داشت بر تعدادی از ویجتهای Kendo UI جهت رسم نمودار. توسط Kendo UI میتوانیم نمودارهای زیر را ترسیم کنیم:
2- سپس یک عنصر را بر روی صفحه جهت نمایش نمودار، تعیین میکنیم:
برای عنصر فوق میتوانیم درون CSS و یا به صورت inline طول و عرضی را برای چارت تعیین کنیم:
با فراخوانی تابع KendoChart، چارت بر روی صفحه نمایش داده میشود:
نمایش دادهها بر روی چارت:
دادهها را میتوان هم به صورت local و هم به صورت remote دریافت و بر روی چارت نمایش داد. اینکار را میتوانیم توسط قسمت series انجام دهیم:
برای تعیین برچسب برای هر یک از دادهها نیز میتوانیم خاصیت category axis را مقداردهی کنیم:
دریافت اطلاعات از سرور:
کدهای سمت سرور:
سپس برای دریافت اطلاعات از سمت سرور باید DataSource مربوط به چارت را مقداردهی کنیم:
همانطور که مشاهده میکنید در این حالت باید برای سری، field و categoryField را مشخص کنیم.
موارد فوق را میتوانیم به صورت یک افزونه نیز کپسوله کنیم.
کدهای افزونه jquery.ChartAjax:
برای افزونه فوق موارد زیر در نظر گرفته شده است:
chartArea : جهت تعیین طول و عرض چارت
theme : جهت تعیین قالبهای از پیشتعریف شده:
دریافت سورس مثال جاری (KendoChart.zip)
- Bar and Column
- Line and Vertical Line
- Area and Vertical Area
- Bullet
- Pie and Donut
- Scatter
- Scatter Line
- Bubble
-
Radar and Polar
برای رسم نمودار میتوانیم به صورت زیر عمل کنیم:
1- ابتدا باید استایلهای مربوط به Data Visualization را به صفحه اضافه کنیم:
<link href="Content/kendo.dataviz.min.css" rel="stylesheet" /> <link href="Content/kendo.dataviz.default.min.css" rel="stylesheet" />
<div id="chart"></div>
<div id="chart" style="width: 400px; height: 600px"></div>
$("#chart").kendoChart();
همانطور که مشاهده میکنید هیچ دادهایی را هنوز برای چارت تعیین نکردهایم؛ در نتیجه همانند تصویر فوق یک چارت خالی بر روی صفحه نمایش داده میشود. برای چارت فوق میتوانیم خواصی از قبیل عنوان و ... را تعیین کنیم:
$("#chart").kendoChart({ title: { text: "چارت آزمایشی" } });
نمایش دادهها بر روی چارت:
دادهها را میتوان هم به صورت local و هم به صورت remote دریافت و بر روی چارت نمایش داد. اینکار را میتوانیم توسط قسمت series انجام دهیم:
$("#chart").kendoChart({ title: { text: "عنوان چارت" }, series: [ { name: "دادههای چارت", data: [200, 450, 300, 125] } ] });
$("#chart").kendoChart({ title: { text: "عنوان چارت" }, series: [ { name: "دادههای چارت", data: [200, 450, 300, 125] } ], categoryAxis: { categories: [2000, 2001, 2002, 2003] } });
دریافت اطلاعات از سرور:
کدهای سمت سرور:
public class ProductsController : ApiController { public IEnumerable<ProductViewModel> Get() { var products = _productService.GetAllProducts(); var query = products.GroupBy(p => p.Name).Select(p => new ProductViewModel { Value = p.Key, Count = p.Count() }); return query; } } public class ProductViewModel { public string Value { get; set; } public int Count { get; set; } }
سپس برای دریافت اطلاعات از سمت سرور باید DataSource مربوط به چارت را مقداردهی کنیم:
var productsDataSource = new kendo.data.DataSource({ transport: { read: { url: "api/products", dataType: "json", contentType: 'application/json; charset=utf-8', type: 'GET' } }, error: function (e) { alert(e.errorThrown.stack); }, pageSize: 5, sort: { field: "Id", dir: "desc" } }); $("#chart").kendoChart({ title: { text: "عنوان چارت" }, dataSource: productsDataSource, series: [ { field: "Count", categoryField: "Value", aggregate: "sum" } ] });
موارد فوق را میتوانیم به صورت یک افزونه نیز کپسوله کنیم.
کدهای افزونه jquery.ChartAjax:
(function($) { $.fn.ShowChart = function(options) { var defaults = { url: '/', text: 'نمودار دایره ایی', theme: 'blueOpal', font: '13px bbc-nassim-bold', legendPosition: 'left', seriesField: 'Count', seriesCategoryField: 'Value', titlePosition: 'top', chartWidth: 400, chartHeight: 400 }; var options = $.extend(defaults, options); return this.each(function() { var chartDataSource = new kendo.data.DataSource({ transport: { read: { url: options.url, dataType: "json", contentType: 'application/json; charset=utf-8', type: 'GET' } }, error: function (e) { // handle error } }); $(this).kendoChart({ chartArea: { height: options.chartHeight }, theme: options.theme, title: { text: options.text, font: options.font, position: options.titlePosition }, legend: { position: options.legendPosition, labels: { font: options.font } }, seriesDefaults: { labels: { visible: false, format: "{0}%" } }, dataSource: chartDataSource, series: [ { type: "pie", field: options.seriesField, categoryField: options.seriesCategoryField, aggregate: "sum", } ], tooltip: { visible: true, template: "${category}: ${value}", font: options.font } }); }); }; })(jQuery);
chartArea : جهت تعیین طول و عرض چارت
theme : جهت تعیین قالبهای از پیشتعریف شده:
- Black
- BlueOpal
- Bootstrap
- Default
- Flat
- HighContrast
- Material
- MaterialBlack
- Metro
- MetroBlack
- Moonlight
- Silver
-
Uniform
title : جهت تعیین عنوان چارت
legend : جهت تنظیم ویژگیهای قسمت گروهبندی چارت
tooltip : جهت تنظیم ویژگیهای مربوط به نمایش tooltip در هنگام hover بر روی چارت.
لازم به ذکر است در قسمت series میتوانید نوع چارت را تعیین کنید.
$('#chart').ShowChart({ url: "/Report/ByUnit", legendPosition: "bottom" });
دریافت سورس مثال جاری (KendoChart.zip)