بهینهسازی کد SQL Server: راهنمای جامع برای کدنویسی فشرده و کارآمد با قابلیتهای نوین
SQL Server در نسخههای جدید خود توابع و امکانات قدرتمندی را معرفی کرده است( IIF , AT TIME ZONE ,…. ) که به توسعهدهندگان SQL Server کمک میکند تا کدنویسی فشردهتر، خواناتر و کارآمدتری داشته باشند. استفاده از این قابلیتهای جدید میتواند در بهینهسازی عملکرد و سادهسازی منطق پیچیده کد نقش کلیدی ایفا کند. در ادامه به بررسی برخی از این توابع کاربردی میپردازیم که میتواند تجربه کدنویسی SQL شما را بهبود بخشد.
استفاده از تابع IIF برای منطق شرطی ساده
تابع `IIF` که از SQL Server 2012 معرفی شد، جایگزینی کوتاهتر و خواناتر برای دستور `CASE` در سناریوهای شرطی ساده است. این تابع یک عبارت بولی را ارزیابی میکند و بر اساس نتیجه (True یا False) یکی از دو مقدار مشخص شده را برمیگرداند. این قابلیت جدید SQL Server به شما اجازه میدهد تا منطق شرطی را به صورت یک خطی بنویسید، که به شدت به فشردهسازی کد SQL کمک میکند.
برای مثال، به جای استفاده از `CASE`، میتوانید از `IIF` برای تعیین یک نتیجه بر اساس یک شرط استفاده کنید:
SELECT IIF(1=1, 'TRUE', 'FALSE') AS Result;
نتیجه اجرای این کد، عبارت `TRUE` خواهد بود. کد معادل با دستور `CASE` به این شکل خواهد بود که کمی طولانیتر است:
SELECT
CASE
WHEN 1=1 THEN 'TRUE'
ELSE 'FALSE'
END AS Result;
همانطور که مشاهده میکنید، `IIF` کدی را ارائه میدهد که فشردهتر و برای سناریوهای شرطی دو گزینهای بهینهتر است.
استفاده از تابع CHOOSE برای انتخاب مقادیر از یک لیست
تابع `CHOOSE` که نیز از SQL Server 2012 در دسترس قرار گرفت، به شما امکان میدهد یک مقدار را از لیستی از گزینهها بر اساس یک ایندکس (موقعیت) عددی انتخاب کنید. این تابع برای مواقعی مفید است که میخواهید یک مقدار را از بین چندین گزینه بر اساس یک عدد صحیح پویا انتخاب کنید، که میتواند کدنویسی SQL را سادهتر کند.
به عنوان نمونه، برای انتخاب یک روز هفته بر اساس یک عدد، میتوانید از `CHOOSE` به این صورت استفاده کنید:
SELECT CHOOSE(3, 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday') AS WeekDay;
این عبارت مقدار `Wednesday` را برمیگرداند زیرا عدد 3 به موقعیت سوم در لیست مقادیر اشاره دارد. استفاده از `CASE` برای همین منظور به شکل زیر خواهد بود:
SELECT
CASE 3
WHEN 1 THEN 'Monday'
WHEN 2 THEN 'Tuesday'
WHEN 3 THEN 'Wednesday'
WHEN 4 THEN 'Thursday'
WHEN 5 THEN 'Friday'
WHEN 6 THEN 'Saturday'
WHEN 7 THEN 'Sunday'
END AS WeekDay;
`CHOOSE` به وضوح کد را سادهتر و خواناتر میکند، بهویژه زمانی که لیست گزینهها طولانی باشد.
ادغام رشتهها با CONCAT_WS
تابع `CONCAT_WS` (Concatenate With Separator) که در SQL Server 2017 معرفی شد، برای الحاق چندین رشته با یک جداکننده مشخص کاربرد دارد. این تابع به طور خودکار مقادیر `NULL` را نادیده میگیرد و این یکی از مزایای اصلی آن نسبت به `CONCAT` یا عملگر `+` است. این ویژگی باعث میشود که کدنویسی SQL شما برای ساخت رشتههای ترکیبی از چندین ستون، به شکل قابل توجهی بهینهتر و بدون نیاز به مدیریت دستی `NULL` ها باشد.
برای مثال، برای ادغام نام، نام میانی و نام خانوادگی با یک فاصله:
SELECT CONCAT_WS(' ', 'John', 'M', 'Doe') AS FullName;
این کد `John M Doe` را برمیگرداند. اگر یکی از مقادیر `NULL` باشد، `CONCAT_WS` آن را به سادگی نادیده میگیرد:
SELECT CONCAT_WS(' ', 'Jane', NULL, 'Smith') AS FullName;
نتیجه این عبارت `Jane Smith` خواهد بود، بدون اینکه نیازی به بررسی `IS NULL` برای هر بخش از نام باشد.
جمعآوری رشتهها با STRING_AGG
تابع `STRING_AGG` که در SQL Server 2017 اضافه شد، یک تابع تجمیعی (aggregate function) است که مقادیر رشتهای را در یک گروه با یک جداکننده مشخص به یکدیگر متصل میکند و یک رشته واحد برمیگرداند. این قابلیت جدید SQL Server برای تولید گزارشها یا فشردهسازی دادههای مرتبط در یک ستون بسیار کارآمد است.
برای مثال، برای جمعآوری تمامی نامهای محصولات در یک لیست جدا شده با کاما:
SELECT STRING_AGG(ProductName, ', ') AS AllProducts
FROM Products;
اگر نیاز به گروهبندی داشته باشید، میتوانید آن را با `GROUP BY` ترکیب کنید. مثلاً، جمعآوری نام محصولات بر اساس دستهبندی:
SELECT Category, STRING_AGG(ProductName, '; ') AS ProductsByCategory
FROM Products
GROUP BY Category;
همچنین میتوانید ترتیب الحاق رشتهها را با استفاده از `WITHIN GROUP (ORDER BY)` مشخص کنید:
SELECT Category, STRING_AGG(ProductName, '; ') WITHIN GROUP (ORDER BY ProductName ASC) AS ProductsByCategoryOrdered
FROM Products
GROUP BY Category;
این تابع به شدت کدنویسی SQL را برای تجمیع رشتهها ساده میکند و نیاز به راهحلهای پیچیدهتر با `FOR XML PATH` را از بین میبرد.
فرمتبندی دادهها با تابع FORMAT
تابع `FORMAT` که در SQL Server 2012 معرفی شد، به شما امکان میدهد مقادیر را با استفاده از یک رشته فرمتبندی مشخص و یک فرهنگ (culture) اختیاری، فرمت کنید. این تابع برای نمایش تاریخها، زمانها و اعداد به فرمتهای متنوع و بومیسازی شده بسیار مفید است. این قابلیت جدید SQL Server به توسعهدهندگان کمک میکند تا نمایش دادهها را در لایه پایگاه داده کنترل کنند.
برای مثال، فرمتبندی یک تاریخ:
SELECT FORMAT(GETDATE(), 'yyyy-MM-dd') AS FormattedDate;
این کد تاریخ فعلی را به فرمت `سال-ماه-روز` برمیگرداند. همچنین میتوانید اعداد را فرمت کنید:
SELECT FORMAT(1234567.89, 'N', 'en-US') AS FormattedNumber;
این عبارت عدد را با کاما برای جداکننده هزارگان و نقطه برای اعشار (بر اساس فرهنگ `en-US`) فرمت میکند و `1,234,567.89` را برمیگرداند.
**ساخت تاریخ و زمان از اجزا با توابع DATEFROMPARTS، DATETIMEFROMPARTS و TIMEFROMPARTS**
این توابع که از SQL Server 2012 به بعد در دسترس هستند، امکان ساخت مقادیر تاریخ، زمان یا تاریخ-زمان را از اجزای تشکیلدهنده آنها (سال، ماه، روز، ساعت، دقیقه و غیره) فراهم میکنند. این روش کدنویسی SQL را برای ایجاد مقادیر تاریخ و زمان از ورودیهای مجزا بسیار ساده و خوانا میکند.
به عنوان مثال:
SELECT
DATEFROMPARTS(2023, 10, 26) AS MyDate,
DATETIMEFROMPARTS(2023, 10, 26, 14, 30, 0, 0) AS MyDateTime,
SMALLDATETIMEFROMPARTS(2023, 10, 26, 14, 30) AS MySmallDateTime,
TIMEFROMPARTS(14, 30, 0, 0, 0) AS MyTime;
این توابع کدنویسی را شفافتر میکنند و از نیاز به تبدیلهای رشتهای پیچیده برای ساخت مقادیر تاریخ و زمان جلوگیری میکنند.
تبدیل منطقه زمانی با AT TIME ZONE
عبارت `AT TIME ZONE` که در SQL Server 2016 معرفی شد، به شما اجازه میدهد تا مقادیر `datetime` را بین مناطق زمانی مختلف تبدیل کنید. این قابلیت جدید SQL Server برای برنامههایی که با دادههای زمانی در مناطق جغرافیایی مختلف سر و کار دارند، حیاتی است و به مدیریت دقیقتر زمان کمک میکند.
برای مثال، تبدیل زمان UTC به منطقه زمانی اقیانوس آرام:
DECLARE @dt DATETIME2 = '2023-10-26 10:00:00.0000000';
SELECT @dt AT TIME ZONE 'UTC' AT TIME ZONE 'Pacific Standard Time' AS PacificTime;
این کد یک `DATETIMEOFFSET` را برمیگرداند که زمان را با احتساب اختلاف منطقه زمانی `Pacific Standard Time` نشان میدهد. این ویژگی بهینهسازی کد را برای مدیریت دادههای زمانی جهانی فراهم میکند.
کار با JSON با تابع OPENJSON
تابع `OPENJSON` که در SQL Server 2016 معرفی شد، یک قابلیت انقلابی برای کار با دادههای JSON است. این تابع متن JSON را تجزیه میکند و اشیاء و ویژگیهای JSON را به صورت مجموعهای از ردیفها و ستونها برمیگرداند. این امکان جدید SQL Server باعث میشود که SQL Server به یک ابزار قدرتمند برای پردازش دادههای غیرساختاریافته JSON تبدیل شود.
برای مثال، استخراج مقادیر ساده از یک رشته JSON:
DECLARE @json NVARCHAR(MAX) = N'{ "name": "John", "age": 30, "city": "New York" }';
SELECT * FROM OPENJSON(@json);
این کوئری یک جدول با ستونهای `key`, `value` و `type` برای هر ویژگی JSON برمیگرداند. برای تعریف صریح طرحواره و استخراج دادهها به ستونهای مشخص، میتوانید از عبارت `WITH` استفاده کنید:
DECLARE @jsonDoc NVARCHAR(MAX) = N'{
"Id": 1,
"Name": "A. Datum Corporation",
"Products": [ {"ProdId": 100, "Qty": 1}, {"ProdId": 101, "Qty": 2} ]
}';
SELECT *
FROM OPENJSON(@jsonDoc)
WITH (
Id INT '$.Id',
Name NVARCHAR(100) '$.Name',
ProductList NVARCHAR(MAX) '$.Products' AS JSON
);
این کوئری به شما امکان میدهد تا مقادیر JSON را به انواع دادهای SQL نگاشت کنید و حتی اشیاء یا آرایههای تودرتو را به عنوان رشتههای JSON جداگانه استخراج کنید. `OPENJSON` یک ابزار بسیار قدرتمند برای توسعهدهندگان SQL Server است که با دادههای JSON سروکار دارند و بهینهسازی کد را در این زمینه به اوج میرساند.