مستندسازی خودکار Stored Procedure SQL Server با XML SQLDMO XSLT

خودکارسازی مستندسازی Stored Procedure ذخیره‌شده SQL Server: رویکردی جامع با XML، SQL-DMO و XSLT

مدیریت و نگهداری روال‌های ذخیره‌شده (Stored Procedures) در پایگاه‌های داده SQL Server، به ویژه در پروژه‌های بزرگ یا تیم‌های توسعه‌دهنده چند نفره، بدون مستندسازی دقیق می‌تواند به سرعت به چالش بزرگی تبدیل شود. این مستندات معمولاً اطلاعات حیاتی مانند نام نویسنده، تاریخ ایجاد، تاریخ آخرین تغییر، پارامترها، توضیحات عملکرد و تغییرات کد را شامل می‌شوند. اما فرآیند مستندسازی دستی وقت‌گیر، مستعد خطا و اغلب از به‌روزرسانی باز می‌ماند.

این مقاله به شما نشان می‌دهد چگونه می‌توانید یک سیستم خودکار برای تولید مستندات روال‌های ذخیره‌شده خود با استفاده از ترکیب قدرتمند SQL Server، XML، SQL-DMO و XSLT بسازید، که هم دقیق باشد و هم به راحتی قابل نگهداری. با پیاده‌سازی این رویکرد، نه تنها زمان توسعه را کاهش می‌دهید، بلکه کیفیت و قابلیت نگهداری کد خود را نیز به طور چشمگیری بهبود می‌بخشید.

محدودیت‌های روش‌های سنتی مستندسازی

مدت‌هاست که SQL Server ابزارهایی برای مشاهده تعاریف روال‌های ذخیره‌شده ارائه می‌دهد، اما این ابزارها برای تولید مستندات جامع کافی نیستند. در ادامه به بررسی دو مورد رایج و محدودیت‌های آن‌ها می‌پردازیم:

استفاده از sp_helptext

رایج‌ترین راه برای مشاهده تعریف یک روال ذخیره‌شده، استفاده از دستور sp_helptext است. این دستور متن روال ذخیره‌شده را برمی‌گرداند، اما آن را در چندین ردیف خروجی می‌دهد که کار با آن برای پردازش خودکار دشوار است.

این کد نحوه استفاده از sp_helptext را نشان می‌دهد:

EXEC sp_helptext 'sp_GetDocumentation'

خروجی این دستور به دلیل تقسیم شدن به چندین ردیف، برای تجزیه و تحلیل ماشینی مناسب نیست و نیاز به پردازش اضافی دارد که پیچیدگی را افزایش می‌دهد.

استفاده مستقیم از syscomments

یک رویکرد بهتر اما همچنان ناکامل، دسترسی مستقیم به جدول سیستمی syscomments است. این جدول حاوی تعریف متنی روال‌های ذخیره‌شده است و می‌توان با یک کوئری ساده آن را بازیابی کرد:

SELECT [text]
FROM syscomments
WHERE id = OBJECT_ID('sp_GetDocumentation')
ORDER BY colid

با این روش، می‌توانید تمام متن روال ذخیره‌شده را در یک فیلد NVARCHAR(MAX) بازیابی کنید، اما همچنان باید متن را برای استخراج پارامترها و سایر جزئیات تجزیه کنید. این کار می‌تواند پیچیده و مستعد خطا باشد، به خصوص زمانی که روال‌های ذخیره‌شده تغییر می‌کنند.

رویکرد مدرن مستندسازی خودکار: XML، SQL-DMO و XSLT

برای غلبه بر محدودیت‌های روش‌های سنتی و ایجاد یک سیستم مستندسازی قدرتمند و انعطاف‌پذیر، ما از سه تکنولوژی اصلی استفاده می‌کنیم: XML برای ذخیره‌سازی داده‌های مستندات، SQL-DMO برای استخراج اطلاعات متا از پایگاه داده و XSLT برای تبدیل این اطلاعات به فرمت قابل خواندن HTML.

۱. استفاده از XML برای ذخیره مستندات

برای حفظ اطلاعات مستندات، پیشنهاد می‌شود آن را به صورت کامنت‌های XML در ابتدای هر روال ذخیره‌شده جاسازی کنید. این کار مزایای زیادی دارد: مستندات همراه با کد اصلی باقی می‌مانند، در کنترل نسخه (Source Control) ردیابی می‌شوند و نیازی به جدول مستندات جداگانه نیست.

نمونه‌ای از ساختار XML که می‌توانید در ابتدای روال ذخیره‌شده قرار دهید:

/*
<documentation>
  <author>FirstName LastName</author>
  <creationDate>yyyy-mm-dd</creationDate>
  <lastModificationDate>yyyy-mm-dd</lastModificationDate>
  <version>1.0</version>
  <description>A short description of what the stored procedure does.</description>
  <changeLog>
    <change>
      <date>yyyy-mm-dd</date>
      <author>FirstName LastName</author>
      <description>Initial creation.</description>
    </change>
  </changeLog>
</documentation>
*/

این ساختار XML امکان ثبت جزئیات دقیق و سازمان‌یافته‌ای را فراهم می‌کند که می‌تواند شامل اطلاعاتی مانند نویسنده، تاریخ ایجاد، نسخه و تاریخچه تغییرات باشد. نگهداری این بلاک XML در ابتدای هر روال ذخیره‌شده، تضمین می‌کند که مستندات همیشه در دسترس و مرتبط با کد باشند.

۲. استخراج اطلاعات با SQL-DMO

SQL-DMO (SQL Distributed Management Objects) یک کتابخانه COM است که امکان دسترسی برنامه‌ریزی‌شده به اشیاء SQL Server را فراهم می‌کند. این ابزار به شما اجازه می‌دهد تا اطلاعات متا از پایگاه داده، از جمله پارامترهای روال‌های ذخیره‌شده و متن کامل آن‌ها، را استخراج کنید. با SQL-DMO می‌توانید به راحتی پارامترها، انواع داده‌ها و مقادیر پیش‌فرض را بازیابی کنید، بدون نیاز به تجزیه دستی متن.

در این پروژه، ما از یک برنامه C# کنسولی برای تعامل با SQL-DMO استفاده می‌کنیم تا به سرور SQL متصل شده، لیست روال‌های ذخیره‌شده را دریافت کنیم، و اطلاعات مورد نیاز را استخراج کنیم. این برنامه سپس داده‌ها را به یک فایل XML استاندارد خروجی می‌دهد.

بخشی از کد C# برای استخراج اطلاعات با استفاده از SQL-DMO:

using System;
using System.Xml;
using SQLDMO; // Reference to Microsoft SQL DMO Object Library

namespace SpDocumentation
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("Usage: SpDocumentation.exe <serverName> <databaseName>");
                return;
            }

            string serverName = args[0];
            string databaseName = args[1];

            SQLDMO.SQLServer server = new SQLDMO.SQLServer();
            try
            {
                server.Connect(serverName, null, null);
                SQLDMO.Database db = server.Databases.Item(databaseName);

                XmlDocument doc = new XmlDocument();
                XmlElement root = doc.CreateElement("StoredProcedures");
                doc.AppendChild(root);

                foreach (SQLDMO.StoredProcedure sp in db.StoredProcedures)
                {
                    XmlElement spNode = doc.CreateElement("StoredProcedure");
                    spNode.SetAttribute("Name", sp.Name);

                    // Extract XML comments
                    string spText = sp.Text;
                    int startIndex = spText.IndexOf("/*<documentation>");
                    int endIndex = spText.IndexOf("</documentation>*/");

                    if (startIndex != -1 && endIndex != -1)
                    {
                        string xmlDoc = spText.Substring(startIndex + 2, endIndex - startIndex - 2 + "</documentation>".Length);
                        try
                        {
                            XmlDocument commentDoc = new XmlDocument();
                            commentDoc.LoadXml(xmlDoc);
                            XmlElement importedNode = (XmlElement)doc.ImportNode(commentDoc.DocumentElement, true);
                            spNode.AppendChild(importedNode);
                        }
                        catch (XmlException)
                        {
                            // Handle malformed XML comments
                        }
                    }

                    // Extract parameters
                    XmlElement paramsNode = doc.CreateElement("Parameters");
                    foreach (SQLDMO.Parameter param in sp.Parameters)
                    {
                        XmlElement paramNode = doc.CreateElement("Parameter");
                        paramNode.SetAttribute("Name", param.Name);
                        paramNode.SetAttribute("DataType", param.DataType);
                        paramNode.SetAttribute("DefaultValue", param.DefaultValue);
                        paramsNode.AppendChild(paramNode);
                    }
                    spNode.AppendChild(paramsNode);
                    root.AppendChild(spNode);
                }
                doc.Save("Documentation.xml");
                Console.WriteLine("Documentation generated successfully to Documentation.xml");
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error: " + ex.Message);
            }
            finally
            {
                server.Disconnect();
            }
        }
    }
}

این کد C# به سرور و پایگاه داده مشخص شده متصل می‌شود، لیست روال‌های ذخیره‌شده را پیمایش می‌کند و اطلاعات متا (مانند پارامترها و متن XML مستندات) را استخراج کرده و در یک فایل XML به نام Documentation.xml ذخیره می‌کند.

۳. تبدیل XML به HTML با XSLT

پس از اینکه تمام اطلاعات مستندات در یک فایل XML جمع‌آوری شد، نیاز داریم آن را به یک فرمت قابل خواندن و نمایش برای کاربران تبدیل کنیم. XSLT (eXtensible Stylesheet Language Transformations) ابزاری قدرتمند برای تبدیل اسناد XML به فرمت‌های دیگر، از جمله HTML است.

با استفاده از یک فایل XSLT، می‌توانیم نحوه نمایش هر بخش از داده‌های XML را تعریف کنیم و یک صفحه HTML زیبا و سازمان‌یافته تولید کنیم. این کار انعطاف‌پذیری بالایی در طراحی خروجی نهایی مستندات به ما می‌دهد.

نمونه‌ای از فایل XSLT (به نام documentation.xslt) که برای تبدیل XML به HTML استفاده می‌شود:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="html" indent="yes"/>

  <xsl:template match="/StoredProcedures">
    <html>
      <head>
        <title>SQL Server Stored Procedure Documentation</title>
        <style>
          body { font-family: Arial, sans-serif; margin: 20px; }
          h1 { color: #333; }
          h2 { color: #555; border-bottom: 1px solid #ccc; padding-bottom: 5px; margin-top: 30px; }
          h3 { color: #777; }
          .sp-container { border: 1px solid #eee; padding: 15px; margin-bottom: 20px; background-color: #f9f9f9; }
          .param-list { list-style-type: none; padding: 0; }
          .param-list li { margin-bottom: 5px; }
          .code-block { background-color: #eef; border: 1px solid #ddd; padding: 10px; font-family: "Courier New", Courier, monospace; overflow-x: auto; }
        </style>
      </head>
      <body>
        <h1>SQL Server Stored Procedure Documentation</h1>
        <xsl:apply-templates select="StoredProcedure"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="StoredProcedure">
    <div class="sp-container">
      <h2>Stored Procedure: <xsl:value-of select="@Name"/></h2>
      
      <!-- Documentation from XML comments -->
      <xsl:if test="documentation">
        <h3>Documentation Details</h3>
        <p><strong>Author:</strong> <xsl:value-of select="documentation/author"/></p>
        <p><strong>Creation Date:</strong> <xsl:value-of select="documentation/creationDate"/></p>
        <p><strong>Last Modified:</strong> <xsl:value-of select="documentation/lastModificationDate"/></p>
        <p><strong>Version:</strong> <xsl:value-of select="documentation/version"/></p>
        <p><strong>Description:</strong> <xsl:value-of select="documentation/description"/></p>
        
        <xsl:if test="documentation/changeLog/change">
          <h4>Change Log:</h4>
          <ul>
            <xsl:for-each select="documentation/changeLog/change">
              <li>
                <strong>Date:</strong> <xsl:value-of select="date"/>, 
                <strong>Author:</strong> <xsl:value-of select="author"/>: 
                <xsl:value-of select="description"/>
              </li>
            </xsl:for-each>
          </ul>
        </xsl:if>
      </xsl:if>

      <!-- Parameters -->
      <xsl:if test="Parameters/Parameter">
        <h3>Parameters</h3>
        <ul class="param-list">
          <xsl:for-each select="Parameters/Parameter">
            <li>
              <strong><xsl:value-of select="@Name"/></strong> 
              (<xsl:value-of select="@DataType"/>)
              <xsl:if test="@DefaultValue != ''">
                = <xsl:value-of select="@DefaultValue"/>
              </xsl:if>
            </li>
          </xsl:for-each>
        </ul>
      </xsl:if>
    </div>
  </xsl:template>

</xsl:stylesheet>

این فایل XSLT یک قالب HTML برای هر روال ذخیره‌شده ایجاد می‌کند، شامل جزئیات مستندات (نویسنده، تاریخ، توضیحات) و لیست پارامترها با نوع داده و مقادیر پیش‌فرض. می‌توانید این XSLT را با استفاده از کتابخانه‌های .NET یا ابزارهای دیگر به HTML تبدیل کنید.

پیاده‌سازی: روال ذخیره‌شده sp_GetDocumentation

برای سهولت فرآیند مستندسازی، می‌توان یک روال ذخیره‌شده به نام sp_GetDocumentation ایجاد کرد. این روال وظیفه دارد تا از برنامه کنسولی C# استفاده کند، اطلاعات را جمع‌آوری کرده و فایل HTML نهایی را تولید کند. این روال ذخیره‌شده از xp_cmdshell برای اجرای برنامه خارجی C# استفاده می‌کند.

نکته مهم: برای استفاده از xp_cmdshell باید آن را در SQL Server فعال کنید. این یک عمل امنیتی است که باید با دقت انجام شود.

کوئری برای فعال کردن xp_cmdshell:

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

حال، تعریف روال ذخیره‌شده sp_GetDocumentation را مشاهده می‌کنید:

CREATE PROCEDURE sp_GetDocumentation
AS
BEGIN
    SET NOCOUNT ON;

    -- Path to the C# executable and XSLT file
    DECLARE @appPath NVARCHAR(255) = 'C:\Path\To\SpDocumentation.exe'; -- Adjust path
    DECLARE @xsltPath NVARCHAR(255) = 'C:\Path\To\documentation.xslt'; -- Adjust path
    DECLARE @outputPath NVARCHAR(255) = 'C:\Path\To\Documentation.html'; -- Adjust path
    
    DECLARE @serverName NVARCHAR(128) = @@SERVERNAME;
    DECLARE @databaseName NVARCHAR(128) = DB_NAME();

    DECLARE @cmd NVARCHAR(MAX);

    -- 1. Run the C# application to generate the XML file
    SET @cmd = @appPath + ' ' + @serverName + ' ' + @databaseName;
    EXEC xp_cmdshell @cmd, NO_OUTPUT;

    -- 2. Transform the XML to HTML using XSLT
    -- This step would typically be done in a separate process or via a .NET assembly
    -- For simplicity, let's assume a separate step or modify the C# app to do this.
    -- If using C#, it could look like:
    -- XslCompiledTransform xslt = new XslCompiledTransform();
    -- xslt.Load(xsltPath);
    -- xslt.Transform("Documentation.xml", outputPath);

    -- For demonstration, if we had a simple way to call XSLT transform directly from SQL:
    -- In a real-world scenario, you might extend the C# app to perform the XSLT transformation
    -- or use SQLCLR for more direct control.

    -- For this example, we'll indicate successful XML generation.
    -- The XSLT transformation step would be handled externally or integrated into the C# app.
    
    -- Simulate the XSLT transformation call (conceptual, not directly executable via xp_cmdshell without helper)
    -- This part is illustrative of the logical step. Actual implementation would involve calling an XSLT processor.
    -- For example, calling another C# app that does the transform, or extending the current one.
    -- The article example does not provide SQL direct call for XSLT, so we stick to the C# application doing XML generation.
    -- The user can then manually run an XSLT transform tool or extend the C# app to do it.

    PRINT 'XML documentation generated. Please use an XSLT processor to convert Documentation.xml to HTML.';
    PRINT 'File: Documentation.xml is located next to SpDocumentation.exe';
END;

این روال ذخیره‌شده با اجرای برنامه C#، فایل XML مستندات را ایجاد می‌کند. سپس، شما می‌توانید فایل Documentation.xml را با استفاده از یک پردازشگر XSLT (مانند ابزارهای خط فرمان، یک برنامه C# دیگر، یا حتی مرورگرهای وب مدرن) به Documentation.html تبدیل کنید.

برای اجرای این روال ذخیره‌شده و تولید مستندات:

EXEC sp_GetDocumentation;

پس از اجرای این دستور، فایل XML مستندات تولید می‌شود و آماده تبدیل به HTML خواهد بود.

نتیجه‌گیری

با ترکیب XML برای ساختارمند کردن داده‌ها، SQL-DMO برای استخراج اطلاعات متا از پایگاه داده و XSLT برای ارائه زیبا و خوانا در HTML، می‌توان یک سیستم خودکار و کارآمد برای مستندسازی روال‌های ذخیره‌شده SQL Server ایجاد کرد. این رویکرد نه تنها بار کاری مستندسازی دستی را کاهش می‌دهد، بلکه تضمین می‌کند که مستندات همیشه به روز و دقیق هستند.

با پیاده‌سازی این راه‌حل، توسعه‌دهندگان می‌توانند زمان بیشتری را صرف نوشتن کد اصلی کنند و اطمینان داشته باشند که مستندات پروژه به صورت خودکار و با کیفیت بالا تولید و نگهداری می‌شوند. این سیستم انعطاف‌پذیری لازم را برای شخصی‌سازی قالب‌های مستندات و انطباق با نیازهای خاص هر پروژه فراهم می‌کند و بهره‌وری تیم‌های توسعه را به طور قابل توجهی افزایش می‌دهد.

 

SP
Comments (0)
Add Comment