Sdílet prostřednictvím


Vytváření vlastních pravidel analýzy kódu

platí pro:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceSQL Database v Microsoft Fabric

Tento názorný postup ukazuje kroky použité k vytvoření pravidla analýzy kódu SQL Serveru. Pravidlo vytvořené v tomto průvodci slouží k tomu, aby se zabránilo příkazům WAITFOR DELAY v uložených procedurách, triggery a funkcích.

V tomto názorném postupu vytvoříte vlastní pravidlo pro Transact-SQL statickou analýzu kódu pomocí následujících kroků:

  1. Vytvořte projekt knihovny tříd, povolte podepisování pro tento projekt a přidejte potřebné odkazy.
  2. Vytvořte dvě pomocné třídy jazyka C#.
  3. Vytvořte vlastní třídu pravidel jazyka C#.
  4. Sestavte projekt knihovny tříd.
  5. Nainstalujte a otestujte nové pravidlo analýzy kódu.

S výjimkou pokynů sady Visual Studio (SQL Server Data Tools) se průvodce zaměřuje na projekty SQL ve stylu sady SDK.

Požadavky

K dokončení tohoto návodu potřebujete následující komponenty:

  • Nainstalovaná verze sady Visual Studio, která zahrnuje SQL Server Data Tools a podporuje vývoj v jazyce C# .NET Framework.
  • Projekt SQL Serveru, který obsahuje objekty SQL Serveru.
  • Instance SQL Serveru, do které můžete nasadit databázový projekt.

Tento názorný postup je určený pro uživatele, kteří už jsou obeznámeni s funkcemi SQL Serveru SQL Server Data Tools. Měli byste znát koncepty sady Visual Studio, například jak vytvořit knihovnu tříd, přidat balíčky NuGet a jak pomocí editoru kódu přidat kód do třídy.

Poznámka

Vzhledem k omezením verze Preview nástrojů SQL Server Data Tools ve stylu sady SDK je k dokončení tohoto návodu potřeba několik instalací sady Visual Studio. První instalace je nutná k vytvoření projektu knihovny tříd, druhá instalace je nutná k vytvoření projektu databáze SQL ve stylu sady SDK.

Tento názorný postup je určený pro uživatele, kteří už jsou obeznámeni s funkcemi SQL Serveru SQL Server Data Tools. Měli byste znát koncepty sady Visual Studio, například jak vytvořit knihovnu tříd, přidat balíčky NuGet a jak pomocí editoru kódu přidat kód do třídy.

  • Nainstalovaná verze editoru Visual Studio Code, která zahrnuje rozšíření SQL Database Projects.
  • Projekt databáze SQL, který obsahuje objekty SQL.
  • .NET 8 SDK
  • Doporučeno: rozšíření C# Dev Kit pro VS Code

Tento názorný postup je určený pro uživatele, kteří už znají rozšíření SQL Database Projects v editoru Visual Studio Code. Měli byste být obeznámeni s koncepty vývoje, jako je vytvoření knihovny tříd, přidání balíčků a použití editoru kódu k úpravě kódu.

  • Textový editor, například editor souborů v editoru Visual Studio Code.
  • Projekt databáze SQL, který obsahuje objekty SQL.
  • .NET 8 SDK

Tento názorný postup je určený pro uživatele, kteří už znají projekty SQL. Měli byste být obeznámeni s koncepty vývoje, jako je vytvoření knihovny tříd, přidání balíčků a použití editoru kódu k úpravě kódu.

Krok 1: Vytvoření projektu knihovny tříd

Nejprve vytvořte knihovnu tříd. Chcete-li vytvořit projekt knihovny tříd:

  1. Vytvořte projekt knihovny tříd C# (.NET Framework) s názvem SampleRules.

  2. Přejmenujte soubor Class1.cs na AvoidWaitForDelayRule.cs.

  3. V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel projektu a pak vyberte Přidat, pak Reference.

  4. Na kartě Sestavení\Frameworks vyberte System.ComponentModel.Composition.

  5. V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel projektu a pak vyberte Spravovat balíčky NuGet. Vyhledejte a nainstalujte balíček NuGet Microsoft.SqlServer.DacFx. Vybraná verze musí být 162.x.x (například 162.2.111) se sadou Visual Studio 2022.

Dále přidejte podpůrné třídy, které bude pravidlo používat.

Nejprve vytvořte knihovnu tříd. Vytvořit projekt knihovny tříd:

  1. Vytvořte projekt knihovny tříd C# (.NET Framework) s názvem SampleRules.

  2. Přejmenujte soubor Class1.cs na AvoidWaitForDelayRule.cs.

  3. V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel projektu a pak vyberte Přidat potom Reference.

  4. Na kartě Sestavení\Frameworks vyberte System.ComponentModel.Composition.

  5. V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel projektu a pak vyberte Spravovat balíčky NuGet. Vyhledejte a nainstalujte balíček NuGet Microsoft.SqlServer.DacFx. Vybraná verze musí být 162.x.x (například 162.2.111) se sadou Visual Studio 2022.

Dále přidejte podpůrné třídy, které bude pravidlo používat.

  1. Spusťte Visual Studio Code a otevřete složku, do které chcete projekt vytvořit.

  2. Otevřete okno terminálu v editoru Visual Studio Code tak, že vyberete nabídku Zobrazení, a potom zvolte Terminál.

  3. V termináluzadejte následující příkazy, které vytvoří nové řešení a projekt:

    dotnet new sln
    dotnet new classlib -n SampleRules -o SampleRules
    dotnet sln add SampleRules/SampleRules.csproj
    
  4. Přejděte do adresáře SampleRules:

    cd SampleRules
    
  5. Přidejte požadovaný balíček NuGet:

    dotnet add package Microsoft.SqlServer.DacFx
    

Dále přidejte podpůrné třídy, které bude pravidlo používat.

  1. Otevřete příkazový řádek nebo okno terminálu a přejděte do složky, do které chcete projekt vytvořit.

  2. V termináluzadejte následující příkazy, které vytvoří nové řešení a projekt:

    dotnet new sln
    dotnet new classlib -n SampleRules -o SampleRules
    dotnet sln add SampleRules/SampleRules.csproj
    
  3. Přejděte do adresáře SampleRules:

    cd SampleRules
    
  4. Přidejte požadovaný balíček NuGet:

    dotnet add package Microsoft.SqlServer.DacFx
    

Krok 2: Vytvoření vlastních pomocných tříd pravidel

Než vytvoříte třídu pro samotné pravidlo, přidejte do projektu třídu návštěvníka a třídu atributu. Tyto třídy můžou být užitečné pro vytváření více vlastních pravidel.

Krok 2.1: Definování třídy WaitForDelayVisitor

První třída, kterou musíte definovat, je WaitForDelayVisitor třída odvozená z TSqlConcreteFragmentVisitor. Tato třída poskytuje přístup k příkazům WAITFOR DELAY v modelu. Třídy návštěvníků využívají rozhraní API ScriptDom poskytované SQL Serverem. V tomto rozhraní API je kód Transact-SQL reprezentován jako abstraktní strom syntaxe (AST) a třídy návštěvníků mohou být užitečné, pokud chcete najít konkrétní objekty syntaxe, jako jsou příkazy WAITFOR DELAY. Tyto příkazy můžou být obtížné najít pomocí objektového modelu, protože nejsou přidružené ke konkrétní vlastnosti objektu nebo relaci, ale můžete je najít pomocí vzoru návštěvníka a ScriptDom API.

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat třídu. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte WaitForDelayVisitor.cs a pak vyberte tlačítko Přidat. Soubor WaitForDelayVisitor.cs je přidán do projektu v Průzkumníku řešení .

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat třídu. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte WaitForDelayVisitor.cs a pak vyberte tlačítko Přidat. Soubor WaitForDelayVisitor.cs je přidán do projektu v Průzkumníku řešení .

  1. Otevřete zobrazení Explorer v editoru Visual Studio Code.

  2. Ve složce SampleRules vytvořte nový soubor s názvem WaitForDelayVisitor.cs.

  1. Přejděte do adresáře SampleRules.
  2. Vytvořte nový soubor s názvem WaitForDelayVisitor.cs.
  1. Otevřete soubor WaitForDelayVisitor.cs a aktualizujte obsah tak, aby odpovídal následujícímu kódu:

    using System.Collections.Generic;
    using Microsoft.SqlServer.TransactSql.ScriptDom;
    namespace SampleRules {
        class WaitForDelayVisitor {}
    }
    
  2. V deklaraci třídy změňte modifikátor přístupu na interní a odvoďte třídu z TSqlConcreteFragmentVisitor:

    internal class WaitForDelayVisitor : TSqlConcreteFragmentVisitor {}
    
  3. Přidejte následující kód, který definuje proměnnou člena Seznamu:

    public IList<WaitForStatement> WaitForDelayStatements { get; private set; }
    
  4. Definujte konstruktor třídy přidáním následujícího kódu:

    public WaitForDelayVisitor() {
       WaitForDelayStatements = new List<WaitForStatement>();
    }
    
  5. Přepište metodu ExplicitVisit přidáním následujícího kódu:

    public override void ExplicitVisit(WaitForStatement node) {
       // We are only interested in WAITFOR DELAY occurrences
       if (node.WaitForOption == WaitForOption.Delay)
          WaitForDelayStatements.Add(node);
    }
    

    Tato metoda navštíví příkazy WAITFOR v modelu a přidá příkazy, které mají DELAY možnost určenou do seznamu příkazů WAITFOR DELAY. Hlavní třída, na kterou je odkazováno, je WaitForStatement.

  6. V nabídce Soubor vyberte Uložit.

Krok 2.2: Přidejte soubor s prostředky a tři řetězce prostředků.

Dále přidejte soubor prostředků, který definuje název pravidla, popis pravidla a kategorii, ve které se pravidlo zobrazí v rozhraní konfigurace pravidla.

  1. V Průzkumníku řešenívyberte projekt SampleRules. V nabídce Project vyberte Přidat, poté Nová položka. Zobrazí se dialogové okno Přidat novou položku.

  2. V seznamu nainstalovaných šablonvyberte Obecné. V podokně podrobností vyberte Soubor zdrojů.

  3. V Názevzadejte RuleResources.resx. Zobrazí se editor prostředků bez jakýchkoli definovaných prostředků.

  4. Definujte čtyři řetězce prostředků následujícím způsobem:

    Jméno Hodnota
    AvoidWaitForDelay_ProblemDescription WAITFOR DELAY statement was found in {0}.
    AvoidWaitForDelay_RuleName Avoid using WaitFor Delay statements in stored procedures, functions and triggers.
    CategorySamples SamplesCategory
    CannotCreateResourceManager Can't create ResourceManager for {0} from {1}.
  5. V nabídce Soubor vyberte Uložit RuleResources.resx.

  1. V Průzkumníku řešenívyberte projekt SampleRules. V nabídce Project vyberte Přidat a pak Nová položka . Zobrazí se dialogové okno Přidat novou položku.

  2. V seznamu Nainstalované Šablonyvyberte Obecné. V podokně podrobností vyberte Soubor prostředků .

  3. V Názevzadejte RuleResources.resx. Editor prostředků se objeví, aniž by byly definovány jakékoli prostředky.

  4. Definujte čtyři řetězce prostředků následujícím způsobem:

    Jméno Hodnota
    AvoidWaitForDelay_ProblemDescription WAITFOR DELAY statement was found in {0}.
    AvoidWaitForDelay_RuleName Avoid using WaitFor Delay statements in stored procedures, functions and triggers.
    CategorySamples SamplesCategory
    CannotCreateResourceManager Can't create ResourceManager for {0} from {1}.
  5. V nabídce Soubor vyberte Uložit RuleResources.resx.

  1. V adresáři SampleRules vytvořte nový soubor s názvem RuleResources.resx.

  2. Otevřete soubor RuleResources.resx a přidejte následující kód:

    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
        <xsd:element name="root" msdata:IsDataSet="true">
          <xsd:complexType>
            <xsd:choice maxOccurs="unbounded">
              <xsd:element name="metadata">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" />
                  </xsd:sequence>
                  <xsd:attribute name="name" use="required" type="xsd:string" />
                  <xsd:attribute name="type" type="xsd:string" />
                  <xsd:attribute name="mimetype" type="xsd:string" />
                  <xsd:attribute ref="xml:space" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="assembly">
                <xsd:complexType>
                  <xsd:attribute name="alias" type="xsd:string" />
                  <xsd:attribute name="name" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="data">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                    <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
                  <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
                  <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
                  <xsd:attribute ref="xml:space" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="resheader">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" />
                </xsd:complexType>
              </xsd:element>
            </xsd:choice>
          </xsd:complexType>
        </xsd:element>
      </xsd:schema>
      <resheader name="resmimetype">
        <value>text/microsoft-resx</value>
      </resheader>
      <resheader name="version">
        <value>2.0</value>
      </resheader>
      <resheader name="reader">
        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <resheader name="writer">
        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <data name="AvoidWaitForDelay_ProblemDescription" xml:space="preserve">
        <value>WAITFOR DELAY statement was found in {0}</value>
      </data>
      <data name="AvoidWaitFormDelay_RuleName" xml:space="preserve">
        <value>Avoid using WaitFor Delay statements in stored procedures, functions and triggers.</value>
      </data>
      <data name="CategorySamples" xml:space="preserve">
        <value>SamplesCategory</value>
      </data>
      <data name="CannotCreateResourceManager" xml:space="preserve">
        <value>Can't create ResourceManager for {0} from {1}</value>
      </data>
    </root>
    
  3. Uložte soubor RuleResources.resx.

  4. Otevřete soubor SampleRules.csproj a přidejte následující kód, který aktualizuje a zahrne obsah zdrojů do projektu:

    <ItemGroup>
      <Compile Update="RuleResources.Designer.cs">
        <DesignTime>True</DesignTime>
        <AutoGen>True</AutoGen>
        <DependentUpon>RuleResources.resx</DependentUpon>
      </Compile>
    </ItemGroup>
    <ItemGroup>
      <EmbeddedResource Include="RuleResources.resx">
        <Generator>PublicResXFileCodeGenerator</Generator>
        <LastGenOutput>RuleResources.Designer.cs</LastGenOutput>
      </EmbeddedResource>
    </ItemGroup>
    
  5. Uložte soubor SampleRules.csproj.

  1. V adresáři SampleRules vytvořte nový soubor s názvem RuleResources.resx.

  2. Otevřete soubor RuleResources.resx a přidejte následující kód:

    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
        <xsd:element name="root" msdata:IsDataSet="true">
          <xsd:complexType>
            <xsd:choice maxOccurs="unbounded">
              <xsd:element name="metadata">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" />
                  </xsd:sequence>
                  <xsd:attribute name="name" use="required" type="xsd:string" />
                  <xsd:attribute name="type" type="xsd:string" />
                  <xsd:attribute name="mimetype" type="xsd:string" />
                  <xsd:attribute ref="xml:space" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="assembly">
                <xsd:complexType>
                  <xsd:attribute name="alias" type="xsd:string" />
                  <xsd:attribute name="name" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="data">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                    <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
                  <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
                  <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
                  <xsd:attribute ref="xml:space" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="resheader">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" />
                </xsd:complexType>
              </xsd:element>
            </xsd:choice>
          </xsd:complexType>
        </xsd:element>
      </xsd:schema>
      <resheader name="resmimetype">
        <value>text/microsoft-resx</value>
      </resheader>
      <resheader name="version">
        <value>2.0</value>
      </resheader>
      <resheader name="reader">
        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <resheader name="writer">
        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <data name="AvoidWaitForDelay_ProblemDescription" xml:space="preserve">
        <value>WAITFOR DELAY statement was found in {0}</value>
      </data>
      <data name="AvoidWaitFormDelay_RuleName" xml:space="preserve">
        <value>Avoid using WaitFor Delay statements in stored procedures, functions and triggers.</value>
      </data>
      <data name="CategorySamples" xml:space="preserve">
        <value>SamplesCategory</value>
      </data>
      <data name="CannotCreateResourceManager" xml:space="preserve">
        <value>Can't create ResourceManager for {0} from {1}</value>
      </data>
    </root>
    
  3. Uložte soubor RuleResources.resx.

  4. Otevřete soubor SampleRules.csproj a přidejte následující kód, který aktualizuje a zahrne obsah zdrojů do projektu:

    <ItemGroup>
      <Compile Update="RuleResources.Designer.cs">
        <DesignTime>True</DesignTime>
        <AutoGen>True</AutoGen>
        <DependentUpon>RuleResources.resx</DependentUpon>
      </Compile>
    </ItemGroup>
    <ItemGroup>
      <EmbeddedResource Include="RuleResources.resx">
        <Generator>PublicResXFileCodeGenerator</Generator>
        <LastGenOutput>RuleResources.Designer.cs</LastGenOutput>
      </EmbeddedResource>
    </ItemGroup>
    
  5. Uložte soubor SampleRules.csproj.

Krok 2.3: Definování třídy LocalizedExportCodeAnalysisRuleAttribute

Druhá třída je LocalizedExportCodeAnalysisRuleAttribute.cs. Jedná se o rozšíření Microsoft.SqlServer.Dac.CodeAnalysis.ExportCodeAnalysisRuleAttribute předdefinovaných frameworkem a podporuje čtení DisplayName a Description používaných vaším pravidlem z konfiguračního souboru prostředků. To je užitečná třída, pokud máte v úmyslu používat pravidla v několika jazycích.

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat třídu. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte LocalizedExportCodeAnalysisRuleAttribute.cs a pak vyberte tlačítko Přidat. Soubor je přidán do projektu v Průzkumníku řešení .

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat třídu. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte LocalizedExportCodeAnalysisRuleAttribute.cs a pak vyberte tlačítko Přidat. Soubor je přidán do projektu v Průzkumníku řešení .

  1. Přejděte do adresáře SampleRules v zobrazení Exploreru v editoru Visual Studio Code.
  2. Vytvořte nový soubor s názvem LocalizedExportCodeAnalysisRuleAttribute.cs.
  1. Přejděte do adresáře SampleRules.
  2. Vytvořte nový soubor s názvem LocalizedExportCodeAnalysisRuleAttribute.cs.
  1. Otevřete soubor a aktualizujte obsah tak, aby odpovídal následujícímu kódu:

    using Microsoft.SqlServer.Dac.CodeAnalysis;
    using System;
    using System.Globalization;
    using System.Reflection;
    using System.Resources;
    
    namespace SampleRules
    {
    
        internal class LocalizedExportCodeAnalysisRuleAttribute : ExportCodeAnalysisRuleAttribute
        {
            private readonly string _resourceBaseName;
            private readonly string _displayNameResourceId;
            private readonly string _descriptionResourceId;
    
            private ResourceManager _resourceManager;
            private string _displayName;
            private string _descriptionValue;
    
            /// <summary>
            /// Creates the attribute, with the specified rule ID, the fully qualified
            /// name of the resource file that will be used for looking up display name
            /// and description, and the Ids of those resources inside the resource file.
            /// </summary>
            public LocalizedExportCodeAnalysisRuleAttribute(
                string id,
                string resourceBaseName,
                string displayNameResourceId,
                string descriptionResourceId)
                : base(id, null)
            {
                _resourceBaseName = resourceBaseName;
                _displayNameResourceId = displayNameResourceId;
                _descriptionResourceId = descriptionResourceId;
            }
    
            /// <summary>
            /// Rules in a different assembly would need to overwrite this
            /// </summary>
            /// <returns></returns>
            protected virtual Assembly GetAssembly()
            {
                return GetType().Assembly;
            }
    
            private void EnsureResourceManagerInitialized()
            {
                var resourceAssembly = GetAssembly();
    
                try
                {
                    _resourceManager = new ResourceManager(_resourceBaseName, resourceAssembly);
                }
                catch (Exception ex)
                {
                    var msg = String.Format(CultureInfo.CurrentCulture, RuleResources.CannotCreateResourceManager, _resourceBaseName, resourceAssembly);
                    throw new RuleException(msg, ex);
                }
            }
    
            private string GetResourceString(string resourceId)
            {
                EnsureResourceManagerInitialized();
                return _resourceManager.GetString(resourceId, CultureInfo.CurrentUICulture);
            }
    
            /// <summary>
            /// Overrides the standard DisplayName and looks up its value inside a resources file
            /// </summary>
            public override string DisplayName
            {
                get
                {
                    if (_displayName == null)
                    {
                        _displayName = GetResourceString(_displayNameResourceId);
                    }
                    return _displayName;
                }
            }
    
            /// <summary>
            /// Overrides the standard Description and looks up its value inside a resources file
            /// </summary>
            public override string Description
            {
                get
                {
                    if (_descriptionValue == null)
                    {
                        _descriptionValue = GetResourceString(_descriptionResourceId);
                    }
                    return _descriptionValue;
                }
            }
        }
    }
    

Krok 2.4: Definování třídy SampleConstants

Dále definujte třídu, která odkazuje na prostředky v souboru prostředků používaném sadou Visual Studio k zobrazení informací o pravidle v uživatelském rozhraní.

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat a potom Třída. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte SampleRuleConstants.cs a vyberte tlačítko Přidat. Soubor SampleRuleConstants.cs přidá se do projektu v Průzkumníku řešení .

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat a potom Třída. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte SampleRuleConstants.cs a poté vyberte tlačítko Přidat. Soubor SampleRuleConstants.cs je přidán do projektu v Průzkumníku řešení .

  1. Přejděte do adresáře SampleRules v zobrazení Exploreru v editoru Visual Studio Code.
  2. Vytvořte nový soubor s názvem SampleRuleConstants.cs.
  1. Přejděte do adresáře SampleRules.
  2. Vytvořte nový soubor s názvem SampleRuleConstants.cs.
  1. Otevřete soubor SampleRuleConstants.cs a do souboru přidejte následující příkazy using:

    namespace SampleRules
    {
        internal static class RuleConstants
        {
            /// <summary>
            /// The name of the resources file to use when looking up rule resources
            /// </summary>
            public const string ResourceBaseName = "SampleRules.RuleResources";
    
            /// <summary>
            /// Lookup name inside the resources file for the select asterisk rule name
            /// </summary>
            public const string AvoidWaitForDelay_RuleName = "AvoidWaitForDelay_RuleName";
            /// <summary>
            /// Lookup ID inside the resources file for the select asterisk description
            /// </summary>
            public const string AvoidWaitForDelay_ProblemDescription = "AvoidWaitForDelay_ProblemDescription";
    
            /// <summary>
            /// The design category (should not be localized)
            /// </summary>
            public const string CategoryDesign = "Design";
    
            /// <summary>
            /// The performance category (should not be localized)
            /// </summary>
            public const string CategoryPerformance = "Design";
        }
    }
    
  2. V nabídce Soubor vyberte Uložit.

Krok 3: Vytvoření vlastní třídy pravidel

Po přidání pomocných tříd, které bude vlastní pravidlo analýzy kódu používat, vytvořte vlastní třídu pravidla a pojmenujte ji AvoidWaitForDelayRule. AvoidWaitForDelayRule vlastní pravidlo se použije pro napomoci vývojářům databází vyvarovat se WAITFOR DELAY příkazům v uložených procedurách, triggerech a funkcích.

Krok 3.1: Vytvoření třídy AvoidWaitForDelayRule

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat pak Třída. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte AvoidWaitForDelayRule.cs a pak vyberte Přidat. Soubor AvoidWaitForDelayRule.cs je přidán do projektu v Průzkumníku řešení .

  1. V Průzkumníku řešenívyberte projekt SampleRules.

  2. V nabídce Project vyberte Přidat a pak Třída. Zobrazí se dialogové okno Přidat novou položku. Do textového pole Název zadejte AvoidWaitForDelayRule.cs a pak vyberte Přidat. Soubor AvoidWaitForDelayRule.cs se přidá do projektu v Průzkumníku řešení .

  1. Přejděte do adresáře SampleRules v zobrazení Exploreru v editoru Visual Studio Code.
  2. Vytvořte nový soubor s názvem AvoidWaitForDelayRule.cs.
  1. Přejděte do adresáře SampleRules.
  2. Vytvořte nový soubor s názvem AvoidWaitForDelayRule.cs.
  1. Otevřete soubor AvoidWaitForDelayRule.cs a do souboru přidejte následující příkazy using:

    using Microsoft.SqlServer.Dac.CodeAnalysis;
    using Microsoft.SqlServer.Dac.Model;
    using Microsoft.SqlServer.TransactSql.ScriptDom;
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    namespace SampleRules {
        class AvoidWaitForDelayRule {}
    }
    
  2. V deklaraci třídy AvoidWaitForDelayRule změňte modifikátor přístupu na veřejný:

    /// <summary>
    /// This is a rule that returns a warning message
    /// whenever there is a WAITFOR DELAY statement appears inside a subroutine body.
    /// This rule only applies to stored procedures, functions and triggers.
    /// </summary>
    public sealed class AvoidWaitForDelayRule
    
  3. Odvodit třídu AvoidWaitForDelayRule ze základní třídy Microsoft.SqlServer.Dac.CodeAnalysis.SqlCodeAnalysisRule:

    public sealed class AvoidWaitForDelayRule : SqlCodeAnalysisRule
    
  4. Přidejte LocalizedExportCodeAnalysisRuleAttribute do své třídy.

    LocalizedExportCodeAnalysisRuleAttribute umožňuje službě analýzy kódu zjišťovat vlastní pravidla analýzy kódu. V analýze kódu lze použít pouze třídy označené ExportCodeAnalysisRuleAttribute (nebo atributem, který z toho dědí).

    LocalizedExportCodeAnalysisRuleAttribute poskytuje některá požadovaná metadata používaná službou. To zahrnuje jedinečné ID pro toto pravidlo, zobrazený název v uživatelském rozhraní sady Visual Studio a Description, které může pravidlo použít při identifikaci problémů.

    [LocalizedExportCodeAnalysisRule(AvoidWaitForDelayRule.RuleId,
        RuleConstants.ResourceBaseName,
        RuleConstants.AvoidWaitForDelay_RuleName,
        RuleConstants.AvoidWaitForDelay_ProblemDescription
        Category = RuleConstants.CategoryPerformance,
        RuleScope = SqlRuleScope.Element)]
    public sealed class AvoidWaitForDelayRule : SqlCodeAnalysisRule
    {
       /// <summary>
       /// The Rule ID should resemble a fully-qualified class name. In the Visual Studio UI
       /// rules are grouped by "Namespace + Category", and each rule is shown using "Short ID: DisplayName".
       /// For this rule, that means the grouping will be "Public.Dac.Samples.Performance", with the rule
       /// shown as "SR1004: Avoid using WaitFor Delay statements in stored procedures, functions and triggers."
       /// </summary>
       public const string RuleId = "RuleSamples.SR1004";
    }
    

    Vlastnost RuleScope by měla být Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleScope.Element, protože toto pravidlo analyzuje konkrétní prvky. Pravidlo se volá jednou pro každý odpovídající prvek v modelu. Pokud chcete analyzovat celý model, můžete místo toho použít Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleScope.Model.

  5. Přidejte konstruktor, který nastavuje Microsoft.SqlServer.Dac.CodeAnalysis.SqlAnalysisRule.SupportedElementTypes. To je vyžadováno pro pravidla s vymezeným prvkem. Definuje typy prvků, na které se toto pravidlo vztahuje. V tomto případě se pravidlo použije pro uložené procedury, triggery a funkce. Třída Microsoft.SqlServer.Dac.Model.ModelSchema obsahuje seznam všech dostupných typů prvků, které lze analyzovat.

    public AvoidWaitForDelayRule()
    {
       // This rule supports Procedures, Functions and Triggers. Only those objects will be passed to the Analyze method
       SupportedElementTypes = new[]
       {
          // Note: can use the ModelSchema definitions, or access the TypeClass for any of these types
          ModelSchema.ExtendedProcedure,
          ModelSchema.Procedure,
          ModelSchema.TableValuedFunction,
          ModelSchema.ScalarFunction,
    
          ModelSchema.DatabaseDdlTrigger,
          ModelSchema.DmlTrigger,
          ModelSchema.ServerDdlTrigger
       };
    }
    
  6. Přidejte přepsání pro metodu Microsoft.SqlServer.Dac.CodeAnalysis.SqlAnalysisRule.Analyze(Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleExecutionContext), která používá Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleExecutionContext jako vstupní parametry. Tato metoda vrátí seznam potenciálních problémů.

    Metoda získá Microsoft.SqlServer.Dac.Model.TSqlModel, Microsoft.SqlServer.Dac.Model.TSqlObjecta TSqlFragment z kontextového parametru. Třída WaitForDelayVisitor se pak použije k získání seznamu všech příkazů WAITFOR DELAY v modelu.

    Pro každý WaitForStatement v seznamu se vytvoří Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleProblem.

    /// <summary>
    /// For element-scoped rules the Analyze method is executed once for every matching
    /// object in the model.
    /// </summary>
    /// <param name="ruleExecutionContext">The context object contains the TSqlObject being
    /// analyzed, a TSqlFragment
    /// that's the AST representation of the object, the current rule's descriptor, and a
    /// reference to the model being
    /// analyzed.
    /// </param>
    /// <returns>A list of problems should be returned. These will be displayed in the Visual
    /// Studio error list</returns>
    public override IList<SqlRuleProblem> Analyze(
        SqlRuleExecutionContext ruleExecutionContext)
    {
         IList<SqlRuleProblem> problems = new List<SqlRuleProblem>();
    
         TSqlObject modelElement = ruleExecutionContext.ModelElement;
    
         // this rule does not apply to inline table-valued function
         // we simply do not return any problem in that case.
         if (IsInlineTableValuedFunction(modelElement))
         {
             return problems;
         }
    
         string elementName = GetElementName(ruleExecutionContext, modelElement);
    
         // The rule execution context has all the objects we'll need, including the
         // fragment representing the object,
         // and a descriptor that lets us access rule metadata
         TSqlFragment fragment = ruleExecutionContext.ScriptFragment;
         RuleDescriptor ruleDescriptor = ruleExecutionContext.RuleDescriptor;
    
         // To process the fragment and identify WAITFOR DELAY statements we will use a
         // visitor
         WaitForDelayVisitor visitor = new WaitForDelayVisitor();
         fragment.Accept(visitor);
         IList<WaitForStatement> waitforDelayStatements = visitor.WaitForDelayStatements;
    
         // Create problems for each WAITFOR DELAY statement found
         // When creating a rule problem, always include the TSqlObject being analyzed. This
         // is used to determine
         // the name of the source this problem was found in and a best guess as to the
         // line/column the problem was found at.
         //
         // In addition if you have a specific TSqlFragment that is related to the problem
         //also include this
         // since the most accurate source position information (start line and column) will
         // be read from the fragment
         foreach (WaitForStatement waitForStatement in waitforDelayStatements)
         {
            SqlRuleProblem problem = new SqlRuleProblem(
                String.Format(CultureInfo.CurrentCulture,
                    ruleDescriptor.DisplayDescription, elementName),
                modelElement,
                waitForStatement);
            problems.Add(problem);
        }
        return problems;
    }
    
    private static string GetElementName(
        SqlRuleExecutionContext ruleExecutionContext,
        TSqlObject modelElement)
    {
        // Get the element name using the built in DisplayServices. This provides a number of
        // useful formatting options to
        // make a name user-readable
        var displayServices = ruleExecutionContext.SchemaModel.DisplayServices;
        string elementName = displayServices.GetElementName(
            modelElement, ElementNameStyle.EscapedFullyQualifiedName);
        return elementName;
    }
    
    private static bool IsInlineTableValuedFunction(TSqlObject modelElement)
    {
        return TableValuedFunction.TypeClass.Equals(modelElement.ObjectType)
                       && FunctionType.InlineTableValuedFunction ==
            modelElement.GetMetadata<FunctionType>(TableValuedFunction.FunctionType);
    }
    
  7. V nabídce Soubor vyberte Uložit.

Krok 4: Sestavení knihovny tříd

  1. V nabídce Project vyberte Vlastnosti ukázkových pravidel.
  2. Vyberte kartu Podepisování.
  3. Vyberte Podepištesestavení .
  4. V Zvolte soubor silného názvu klíče, vyberte <Nový>.
  5. V dialogovém okně Vytvořit klíč silného názvu , v poli Název souboru klíče, zadejte MyRefKey.
  6. (volitelné) Můžete zadat heslo pro soubor veřejného klíče se silným názvem.
  7. Vyberte OK.
  8. V nabídce Soubor vyberte Uložit vše.
  9. V nabídce Sestavení vyberte řešení sestavení.
  1. V nabídce Project vyberte vlastnosti SampleRules.
  2. Vyberte kartu Podepisování.
  3. Vyberte a podepište sestavení.
  4. V Zvolte soubor se silným názvem klíčea vyberte <Nový>.
  5. V dialogovém okně Vytvořit klíč silného názvu, do název klíčového souboruzadejte MyRefKey.
  6. (volitelné) Můžete zadat heslo pro klíčový soubor se silným názvem.
  7. Vyberte OK.
  8. V nabídce Soubor vyberte Uložit vše.
  9. V nabídce Sestavení vyberte řešení sestavení.
  1. Otevřete okno Terminál v editoru Visual Studio Code tak, že vyberete nabídku Zobrazit a poté Terminál.

  2. V termináluzadejte následující příkaz, který projekt sestaví:

    dotnet build /p:Configuration=Release
    
  1. Přejděte do adresáře SampleRules.

  2. Spuštěním následujícího příkazu sestavte projekt:

    dotnet build /p:Configuration=Release
    

Krok 5: Instalace a testování nového pravidla analýzy kódu

Dále je nutné nainstalovat sestavení, aby se načítá při sestavení projektu databáze SQL.

Chcete-li nainstalovat pravidlo, které se spustí při sestavení původního projektu SQL pomocí sady Visual Studio, musíte zkopírovat sestavení a přidružené .pdb soubor do složky Extensions.

Krok 5.1: Instalace sestavení SampleRules

  1. Dále zkopírujte informace o sestavení do adresáře Rozšíření. Při spuštění sady Visual Studio identifikuje všechna rozšíření v <Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions adresářích a podadresářích a zpřístupní je pro použití. Pro Visual Studio 2022 je <Visual Studio Install Dir> obvykle C:\Program Files\Microsoft Visual Studio\2022\Enterprise. V závislosti na nainstalované edici sady Visual Studio nahraďte EnterpriseProfessional nebo Community.
  2. Zkopírujte soubor sestavení SampleRules.dll z výstupního adresáře do <Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions adresáře. Ve výchozím nastavení je cesta kompilovaného souboru .dllYourSolutionPath\YourProjectPath\bin\Debug nebo YourSolutionPath\YourProjectPath\bin\Release.

Poznámka

Možná budete muset vytvořit Extensions adresář.

Vaše pravidlo by se teď mělo nainstalovat a po restartování sady Visual Studio se zobrazí. Dále spusťte novou relaci sady Visual Studio a vytvořte databázový projekt.

Krok 5.2: Spuštění nové relace sady Visual Studio a vytvoření databázového projektu

  1. Spusťte druhou relaci sady Visual Studio.
  2. Vyberte Soubor>Nový>Projekt.
  3. V dialogovém okně Nový projekt vyhledejte a vyberte projekt databáze SQL Serveru.
  4. Do textového pole Název zadejte SampleRulesDB a vyberte OK.

Krok 5.3: Povolení pravidla analýzy kódu AvoidWaitForRule

  1. V Průzkumníku řešenívyberte projekt SampleRulesDB.
  2. V nabídce Project vyberte Vlastnosti. Zobrazí se stránka vlastností SampleRulesDB.
  3. Vyberte analýza kódu. Měla by se zobrazit nová kategorie s názvem RuleSamples.CategorySamples.
  4. Rozbalte RuleSamples.CategorySamples. Měli byste vidět SR1004: Avoid WAITFOR DELAY statement in stored procedures, triggers, and functions.
  5. Toto pravidlo povolte zaškrtnutím políčka vedle názvu pravidla a políčka pro Povolit analýzu kódu při sestavení. Další informace o povolení analýzy kódu najdete v přehledu analýzy kódu .
  6. Když se použije akce projektu sestavení, pravidlo se spustí a všechny nalezené příkazy WAITFOR DELAY se ohlásí jako upozornění.

Chcete-li nainstalovat pravidlo, které se spustí při sestavení původního projektu SQL pomocí sady Visual Studio, musíte zkopírovat sestavení a přidružené .pdb soubor do složky Extensions.

Krok 5.1: Instalace sestavení SampleRules

  1. Dále zkopírujte informace o sestavení do adresáře Rozšíření. Při spuštění sady Visual Studio identifikuje všechna rozšíření v <Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions adresářích a podadresářích a zpřístupní je pro použití. Pro Visual Studio 2022 je <Visual Studio Install Dir> obvykle C:\Program Files\Microsoft Visual Studio\2022\Enterprise. V závislosti na nainstalované edici sady Visual Studio nahraďte EnterpriseProfessional nebo Community.
  2. Zkopírujte soubor sestavení SampleRules.dll z výstupního adresáře do <Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions adresáře. Ve výchozím nastavení je cesta kompilovaného souboru .dllYourSolutionPath\YourProjectPath\bin\Debug nebo YourSolutionPath\YourProjectPath\bin\Release.

Poznámka

Možná budete muset vytvořit Extensions adresář.

Vaše pravidlo by se teď mělo nainstalovat a po restartování sady Visual Studio se zobrazí. Dále spusťte novou relaci sady Visual Studio a vytvořte databázový projekt.

Krok 5.2: Spuštění nové relace sady Visual Studio a vytvoření databázového projektu

  1. Spusťte druhou relaci sady Visual Studio.
  2. Vyberte Soubor>Nový>Projekt.
  3. V dialogovém okně Nový projekt vyhledejte a vyberte projekt databáze SQL Serveru, styl sady SDK (Preview).
  4. Do textového pole Název zadejte SampleRulesDB a vyberte OK.

Krok 5.3: Povolení pravidla analýzy kódu AvoidWaitForRule

  1. V Průzkumníku řešenívyberte projekt SampleRulesDB.
  2. Poklikáním na uzel projektu otevřete soubor projektu. Soubor projektu SampleRulesDB se zobrazí v textovém editoru.
  3. Povolení analýzy kódu při sestavení v souboru projektu SQL můžete dosáhnout nastavením vlastnosti RunSqlCodeAnalysis na true.
  4. Když se použije akce projektu sestavení, pravidlo se spustí a všechny nalezené příkazy WAITFOR DELAY budou ohlášeny jako upozornění.

Krok 5.1: Umístění sestavení SampleRules do místního zdroje NuGet

  1. Pokud nemáte místní zdroj balíčků NuGet, přidejte do místního počítače složku pro ukládání balíčků NuGet pro místní testování. Aktuální zdroje NuGet můžete zkontrolovat spuštěním následujícího příkazu:
dotnet nuget list source
  1. Pokud místní zdroj není uvedený, můžete ho přidat pomocí následujícího příkazu a nahradit <local folder path> cestou k místní složce, například C:\NuGetPackages nebo ~/NuGetPackages:
dotnet nuget add source <local folder path>
  1. Zkopírujte soubor sestavení SampleRules.dll z výstupního adresáře do místního zdrojového adresáře NuGet. Ve výchozím nastavení je cesta kompilovaného souboru .dllYourSolutionPath\YourProjectPath\bin\Debug nebo YourSolutionPath\YourProjectPath\bin\Release.

Krok 5.2: Použití vzorových pravidel v databázovém projektu

  1. Vytvořte nový projekt Microsoft.Build.Sql nebo otevřete existující projekt.
  2. Přidejte odkaz na balíček do balíčku SampleRules NuGet v souboru projektu. Následující příklad ukazuje, jak přidat odkaz na balíček SampleRules NuGet v souboru .sqlproj:
<ItemGroup>
  <PackageReference Include="SampleRules" Version="1.0.0" />
</ItemGroup>

Krok 5.3: Povolení analýzy kódu při sestavení

  1. Povolte analýzu kódu pro sestavení v souboru projektu SQL tak, že nastavíte vlastnost RunSqlCodeAnalysis na true. Balíček SampleRules NuGet se obnoví při sestavení a zahrnutí projektu ve výchozím nastavení.
  2. Když se použije akce sestavení sestavení, pravidlo se spustí a všechny nalezené příkazy WAITFOR DELAY se ohlásí jako upozornění.

Krok 5.1: Umístění sestavení SampleRules do místního zdroje NuGet

  1. Pokud nemáte místní zdroj balíčků NuGet, přidejte do místního počítače složku pro ukládání balíčků NuGet pro místní testování. Aktuální zdroje NuGet můžete zkontrolovat spuštěním následujícího příkazu:
dotnet nuget list source
  1. Pokud místní zdroj není uvedený, můžete ho přidat pomocí následujícího příkazu a nahradit <local folder path> cestou k místní složce, například C:\NuGetPackages nebo ~/NuGetPackages:
dotnet nuget add source <local folder path>
  1. Zkopírujte soubor sestavení SampleRules.dll z výstupního adresáře do místního zdrojového adresáře NuGet. Ve výchozím nastavení je cesta kompilovaného souboru .dllYourSolutionPath\YourProjectPath\bin\Debug nebo YourSolutionPath\YourProjectPath\bin\Release.

Krok 5.2: Použití vzorových pravidel v databázovém projektu

  1. Vytvořte nový projekt Microsoft.Build.Sql nebo otevřete existující projekt.
  2. Přidejte odkaz na balíček do balíčku SampleRules NuGet v souboru projektu. Následující příklad ukazuje, jak přidat odkaz na balíček SampleRules NuGet v souboru .sqlproj:
<ItemGroup>
  <PackageReference Include="SampleRules" Version="1.0.0" />
</ItemGroup>

Krok 5.3: Povolení analýzy kódu při sestavení

  1. Povolte analýzu kódu během sestavení v souboru projektu SQL nastavením vlastnosti RunSqlCodeAnalysis na true. Balíček SampleRules NuGet se obnoví při sestavení a zahrnutí projektu ve výchozím nastavení.
  2. Když se použije akce projektu sestavení, pravidlo se spustí a všechny příkazy WAITFOR DELAY, které budou nalezeny, se ohlásí jako upozornění.