راهکار نوین برای مشاهده کد SQL بدون شکستگی خطوط با جایگزین sp_helptext
رویه ذخیرهشده سیستمی `sp_helptext` مدتهاست که وجود دارد و امکان مشاهده کد T-SQL رویههای ذخیرهشده، ویوها، توابع و تریگرها را فراهم میکند. یکی از بزرگترین گلایهها از `sp_helptext` این است که خطوط کد را به تکههای ۲۵۵ کاراکتری تقسیم میکند. این موضوع میتواند خواندن کد را بسیار دشوار کند، به خصوص زمانی که خطوط کد طولانیتری دارید و به دنبال *بهبود خوانایی کد T-SQL* هستید. این مشکل به خصوص در *مشاهده کد SQL* برای اهداف عیبیابی و توسعه آزاردهنده است و بر *ابزار توسعه SQL* تأثیر میگذارد.
ویو سیستمی اصلی که `sp_helptext` از آن استفاده میکند، `sys.sql_modules` است. این ویو تعریف شیء را در یک ستون واحد ذخیره میکند. برای مثال، مشخصات این ستون به شرح زیر است:
NVARCHAR(MAX)
این ستون قادر به نگهداری رشتههای یونیکد با حداکثر طول ممکن است. بنابراین اگر یک دستور `SELECT` ساده را در برابر `sys.sql_modules` اجرا کنید، کل تعریف کد را یکجا مشاهده خواهید کرد که راهی برای *مشاهده کد SQL* است.
برای یافتن تعریف یک شیء خاص، از `OBJECT_ID` استفاده میکنیم که شناسه شیء را برمیگرداند. ساختار آن به صورت زیر است:
OBJECT_ID(@objname)
مثال:
SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('usp_LoadFiles');
این رویکرد برای مشاهده کامل کد یکجا عالی است، اما فرمتبندی زیبا و خوانایی که `sp_helptext` ارائه میدهد، مانند استفاده از فونت متفاوت و تورفتگیها را ندارد. اینجاست که نیاز به یک *جایگزین sp_helptext* برای *بهبود خوانایی کد SQL* احساس میشود.
برای بهرهمندی از هر دو مزیت، یک رویه ذخیرهشده ساده ایجاد کردهام که کل تعریف شیء را به ما میدهد و همچنین آن را به شکلی مشابه با خروجی `sp_helptext` فرمتبندی میکند. این رویه، *ابزار توسعه SQL* شما را تقویت خواهد کرد و *مشکل تقسیم خطوط کد SQL* را برطرف میکند.
IF OBJECT_ID('dbo.sp_helptext2') IS NOT NULL DROP PROCEDURE dbo.sp_helptext2; GO CREATE PROCEDURE dbo.sp_helptext2 (@objname AS NVARCHAR(MAX)) AS BEGIN DECLARE @Definition AS NVARCHAR(MAX); SELECT @Definition = sm.definition FROM sys.sql_modules AS sm WHERE sm.object_id = OBJECT_ID(@objname); PRINT @Definition; END; GO
این رویه ذخیرهشده ساده، نام شیء را به عنوان پارامتر میگیرد، سپس `sys.sql_modules` را برای دریافت تعریف شیء کوئری میکند. پس از دریافت تعریف، از `PRINT` برای نمایش دادهها در پنجره نتایج استفاده میشود. `PRINT` کل رشته را به صورت یک تکه و بدون تقسیم به خطوط متعدد خروجی میدهد. این یک *راهکار نوین برای مشاهده کد SQL* است.
مثال استفاده:
EXEC sp_helptext2 'usp_LoadFiles';
این خوب است، اما اگر بخواهید به تعریف یک جدول یا هر شیء دیگری که در `sys.sql_modules` نیست نگاه کنید، چه؟ برای مدیریت این سناریو، میتوانیم `sys.objects` و `sys.columns` را به کد اضافه کنیم و *ابزار توسعه SQL* خود را کاملتر کنیم. این رویکرد به ما کمک میکند تا *مشکل شکستگی خطوط کد* را برای انواع اشیاء مختلف در SQL Server حل کنیم و یک *جایگزین sp_helptext* جامعتر داشته باشیم.
در ادامه، نسخه کاملتر `sp_helptext2` ارائه شده است که قابلیت نمایش تعریف جداول را نیز دارد:
IF OBJECT_ID('dbo.sp_helptext2') IS NOT NULL DROP PROCEDURE dbo.sp_helptext2; GO CREATE PROCEDURE dbo.sp_helptext2 (@objname AS NVARCHAR(MAX)) AS BEGIN DECLARE @Definition AS NVARCHAR(MAX); DECLARE @objid AS INT; SET @objid = OBJECT_ID(@objname); -- بررسی میکند که آیا شیء یک شیء قابل برنامهریزی (رویه ذخیرهشده، ویو، تابع، تریگر) است IF EXISTS (SELECT 1 FROM sys.sql_modules WHERE object_id = @objid) BEGIN SELECT @Definition = sm.definition FROM sys.sql_modules AS sm WHERE sm.object_id = @objid; PRINT @Definition; END -- بررسی میکند که آیا شیء یک جدول است ELSE IF EXISTS (SELECT 1 FROM sys.tables WHERE object_id = @objid) BEGIN SELECT @Definition = N'CREATE TABLE [' + SCHEMA_NAME(t.schema_id) + N'].[' + t.name + N'] (' + CHAR(13) + CHAR(10) FROM sys.tables AS t WHERE t.object_id = @objid; SELECT @Definition = @Definition + N' [' + c.name + N'] ' + TYPE_NAME(c.user_type_id) + CASE WHEN TYPE_NAME(c.user_type_id) IN (N'varchar', N'nvarchar', N'varbinary') THEN N'(' + IIF(c.max_length = -1, N'MAX', CAST(c.max_length AS NVARCHAR(MAX))) + N')' WHEN TYPE_NAME(c.user_type_id) IN (N'char', N'nchar', N'binary') THEN N'(' + CAST(c.max_length AS NVARCHAR(MAX)) + N')' WHEN TYPE_NAME(c.user_type_id) IN (N'decimal', N'numeric') THEN N'(' + CAST(c.precision AS NVARCHAR(MAX)) + N',' + CAST(c.scale AS NVARCHAR(MAX)) + N')' ELSE N'' END + CASE WHEN c.is_nullable = 1 THEN N' NULL' ELSE N' NOT NULL' END + CASE WHEN dc.definition IS NOT NULL THEN N' DEFAULT ' + dc.definition ELSE N'' END + CASE WHEN ic.is_identity = 1 THEN N' IDENTITY(' + CAST(ISNULL(ic.seed_value, 0) AS NVARCHAR(MAX)) + N',' + CAST(ISNULL(ic.increment_value, 1) AS NVARCHAR(MAX)) + N')' ELSE N'' END + CASE WHEN c.column_id < (SELECT MAX(column_id) FROM sys.columns WHERE object_id = @objid) THEN N',' ELSE N'' END + CHAR(13) + CHAR(10) FROM sys.columns AS c LEFT JOIN sys.default_constraints AS dc ON dc.parent_object_id = c.object_id AND dc.parent_column_id = c.column_id LEFT JOIN sys.identity_columns AS ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id WHERE c.object_id = @objid ORDER BY c.column_id; SELECT @Definition = @Definition + N')'; PRINT @Definition; END ELSE BEGIN PRINT N'Object ' + QUOTENAME(@objname) + N' not found or not supported.'; END END; GO
این نسخه پیشرفته `sp_helptext2` ابتدا بررسی میکند که آیا شیء مورد نظر یک شیء برنامهریزیپذیر (مانند رویه ذخیرهشده یا ویو) است یا یک جدول. اگر یک شیء برنامهریزیپذیر باشد، تعریف آن را از `sys.sql_modules` بازیابی میکند. اگر یک جدول باشد، با استفاده از `sys.tables` و `sys.columns`، دستور `CREATE TABLE` مربوطه را بازسازی میکند. این رویکرد به ما امکان *مشاهده کد SQL* با فرمتبندی مناسب و بدون *مشکل تقسیم خطوط کد* را برای طیف وسیعتری از اشیاء پایگاه داده میدهد، که یک *راهکار نوین* و کارآمد برای توسعهدهندگان SQL است. این *جایگزین sp_helptext* یک ابزار قدرتمند برای *بهبود خوانایی کد T-SQL* و افزایش کارایی در *ابزار توسعه SQL* شماست.