Vytváření vlastních pravidel analýzy kódu
platí pro:SQL Server
Azure SQL Database
Azure SQL Managed Instance
SQL 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ů:
- Vytvořte projekt knihovny tříd, povolte podepisování pro tento projekt a přidejte potřebné odkazy.
- Vytvořte dvě pomocné třídy jazyka C#.
- Vytvořte vlastní třídu pravidel jazyka C#.
- Sestavte projekt knihovny tříd.
- 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.
- .NET 8 SDK
- Visual Studio 2022 Community, Professional nebo Enterprise
- SQL Server Data Tools, sada SDK (Preview) nainstalovaná v sadě Visual Studio 2022
- Nainstalovaná verze sady Visual Studio, která podporuje vývoj v jazyce C# .NET.
- Projekt SQL Serveru, který obsahuje objekty SQL Serveru.
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:
Vytvořte projekt knihovny tříd C# (.NET Framework) s názvem
SampleRules
.Přejmenujte soubor
Class1.cs
naAvoidWaitForDelayRule.cs
.V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel projektu a pak vyberte Přidat, pak Reference.
Na kartě Sestavení\Frameworks vyberte
System.ComponentModel.Composition
.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ýt162.x.x
(například162.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:
Vytvořte projekt knihovny tříd C# (.NET Framework) s názvem
SampleRules
.Přejmenujte soubor
Class1.cs
naAvoidWaitForDelayRule.cs
.V Průzkumníku řešení klikněte pravým tlačítkem myši na uzel projektu a pak vyberte Přidat potom Reference.
Na kartě Sestavení\Frameworks vyberte
System.ComponentModel.Composition
.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ýt162.x.x
(například162.2.111
) se sadou Visual Studio 2022.
Dále přidejte podpůrné třídy, které bude pravidlo používat.
Spusťte Visual Studio Code a otevřete složku, do které chcete projekt vytvořit.
Otevřete okno terminálu v editoru Visual Studio Code tak, že vyberete nabídku Zobrazení, a potom zvolte Terminál.
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
Přejděte do adresáře
SampleRules
:cd SampleRules
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.
Otevřete příkazový řádek nebo okno terminálu a přejděte do složky, do které chcete projekt vytvořit.
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
Přejděte do adresáře
SampleRules
:cd SampleRules
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.
V Průzkumníku řešenívyberte projekt
SampleRules
.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. SouborWaitForDelayVisitor.cs
je přidán do projektu v Průzkumníku řešení .
V Průzkumníku řešenívyberte projekt
SampleRules
.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. SouborWaitForDelayVisitor.cs
je přidán do projektu v Průzkumníku řešení .
Otevřete zobrazení Explorer v editoru Visual Studio Code.
Ve složce
SampleRules
vytvořte nový soubor s názvemWaitForDelayVisitor.cs
.
- Přejděte do adresáře
SampleRules
. - Vytvořte nový soubor s názvem
WaitForDelayVisitor.cs
.
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 {} }
V deklaraci třídy změňte modifikátor přístupu na interní a odvoďte třídu z
TSqlConcreteFragmentVisitor
:internal class WaitForDelayVisitor : TSqlConcreteFragmentVisitor {}
Přidejte následující kód, který definuje proměnnou člena Seznamu:
public IList<WaitForStatement> WaitForDelayStatements { get; private set; }
Definujte konstruktor třídy přidáním následujícího kódu:
public WaitForDelayVisitor() { WaitForDelayStatements = new List<WaitForStatement>(); }
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.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.
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.V seznamu nainstalovaných šablonvyberte Obecné. V podokně podrobností vyberte Soubor zdrojů.
V Názevzadejte
RuleResources.resx
. Zobrazí se editor prostředků bez jakýchkoli definovaných prostředků.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}.
V nabídce Soubor vyberte Uložit RuleResources.resx.
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.V seznamu Nainstalované Šablonyvyberte Obecné. V podokně podrobností vyberte Soubor prostředků .
V Názevzadejte
RuleResources.resx
. Editor prostředků se objeví, aniž by byly definovány jakékoli prostředky.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}.
V nabídce Soubor vyberte Uložit RuleResources.resx.
V adresáři
SampleRules
vytvořte nový soubor s názvemRuleResources.resx
.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>
Uložte soubor
RuleResources.resx
.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>
Uložte soubor
SampleRules.csproj
.
V adresáři
SampleRules
vytvořte nový soubor s názvemRuleResources.resx
.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>
Uložte soubor
RuleResources.resx
.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>
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.
V Průzkumníku řešenívyberte projekt
SampleRules
.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í .
V Průzkumníku řešenívyberte projekt
SampleRules
.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í .
- Přejděte do adresáře
SampleRules
v zobrazení Exploreru v editoru Visual Studio Code. - Vytvořte nový soubor s názvem
LocalizedExportCodeAnalysisRuleAttribute.cs
.
- Přejděte do adresáře
SampleRules
. - Vytvořte nový soubor s názvem
LocalizedExportCodeAnalysisRuleAttribute.cs
.
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í.
V Průzkumníku řešenívyberte projekt
SampleRules
.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. SouborSampleRuleConstants.cs
přidá se do projektu v Průzkumníku řešení .
V Průzkumníku řešenívyberte projekt
SampleRules
.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. SouborSampleRuleConstants.cs
je přidán do projektu v Průzkumníku řešení .
- Přejděte do adresáře
SampleRules
v zobrazení Exploreru v editoru Visual Studio Code. - Vytvořte nový soubor s názvem
SampleRuleConstants.cs
.
- Přejděte do adresáře
SampleRules
. - Vytvořte nový soubor s názvem
SampleRuleConstants.cs
.
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"; } }
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
V Průzkumníku řešenívyberte projekt
SampleRules
.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. SouborAvoidWaitForDelayRule.cs
je přidán do projektu v Průzkumníku řešení .
V Průzkumníku řešenívyberte projekt
SampleRules
.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. SouborAvoidWaitForDelayRule.cs
se přidá do projektu v Průzkumníku řešení .
- Přejděte do adresáře
SampleRules
v zobrazení Exploreru v editoru Visual Studio Code. - Vytvořte nový soubor s názvem
AvoidWaitForDelayRule.cs
.
- Přejděte do adresáře
SampleRules
. - Vytvořte nový soubor s názvem
AvoidWaitForDelayRule.cs
.
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 {} }
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
Odvodit třídu
AvoidWaitForDelayRule
ze základní třídyMicrosoft.SqlServer.Dac.CodeAnalysis.SqlCodeAnalysisRule
:public sealed class AvoidWaitForDelayRule : SqlCodeAnalysisRule
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 aDescription
, 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žítMicrosoft.SqlServer.Dac.CodeAnalysis.SqlRuleScope.Model
.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řídaMicrosoft.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 }; }
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.TSqlObject
a TSqlFragment z kontextového parametru. TřídaWaitForDelayVisitor
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); }
V nabídce Soubor vyberte Uložit.
Krok 4: Sestavení knihovny tříd
- V nabídce Project vyberte Vlastnosti ukázkových pravidel.
- Vyberte kartu Podepisování.
- Vyberte Podepištesestavení .
- V Zvolte soubor silného názvu klíče, vyberte <Nový>.
- V dialogovém okně Vytvořit klíč silného názvu , v poli Název souboru klíče, zadejte
MyRefKey
. - (volitelné) Můžete zadat heslo pro soubor veřejného klíče se silným názvem.
- Vyberte OK.
- V nabídce Soubor vyberte Uložit vše.
- V nabídce Sestavení vyberte řešení sestavení.
- V nabídce Project vyberte vlastnosti SampleRules.
- Vyberte kartu Podepisování.
- Vyberte a podepište sestavení.
- V Zvolte soubor se silným názvem klíčea vyberte <Nový>.
- V dialogovém okně Vytvořit klíč silného názvu, do název klíčového souboruzadejte
MyRefKey
. - (volitelné) Můžete zadat heslo pro klíčový soubor se silným názvem.
- Vyberte OK.
- V nabídce Soubor vyberte Uložit vše.
- V nabídce Sestavení vyberte řešení sestavení.
Otevřete okno Terminál v editoru Visual Studio Code tak, že vyberete nabídku Zobrazit a poté Terminál.
V termináluzadejte následující příkaz, který projekt sestaví:
dotnet build /p:Configuration=Release
Přejděte do adresáře
SampleRules
.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
- 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>
obvykleC:\Program Files\Microsoft Visual Studio\2022\Enterprise
. V závislosti na nainstalované edici sady Visual Studio nahraďteEnterprise
Professional
neboCommunity
. - 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.dll
YourSolutionPath\YourProjectPath\bin\Debug
neboYourSolutionPath\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
- Spusťte druhou relaci sady Visual Studio.
- Vyberte Soubor>Nový>Projekt.
- V dialogovém okně Nový projekt vyhledejte a vyberte projekt databáze SQL Serveru.
- Do textového pole Název zadejte
SampleRulesDB
a vyberte OK.
Krok 5.3: Povolení pravidla analýzy kódu AvoidWaitForRule
- V Průzkumníku řešenívyberte projekt
SampleRulesDB
. - V nabídce Project vyberte Vlastnosti. Zobrazí se stránka vlastností
SampleRulesDB
. - Vyberte analýza kódu. Měla by se zobrazit nová kategorie s názvem
RuleSamples.CategorySamples
. - Rozbalte
RuleSamples.CategorySamples
. Měli byste vidětSR1004: Avoid WAITFOR DELAY statement in stored procedures, triggers, and functions
. - 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 .
- 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
- 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>
obvykleC:\Program Files\Microsoft Visual Studio\2022\Enterprise
. V závislosti na nainstalované edici sady Visual Studio nahraďteEnterprise
Professional
neboCommunity
. - 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.dll
YourSolutionPath\YourProjectPath\bin\Debug
neboYourSolutionPath\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
- Spusťte druhou relaci sady Visual Studio.
- Vyberte Soubor>Nový>Projekt.
- V dialogovém okně Nový projekt vyhledejte a vyberte projekt databáze SQL Serveru, styl sady SDK (Preview).
- Do textového pole Název zadejte
SampleRulesDB
a vyberte OK.
Krok 5.3: Povolení pravidla analýzy kódu AvoidWaitForRule
- V Průzkumníku řešenívyberte projekt
SampleRulesDB
. - Poklikáním na uzel projektu otevřete soubor projektu. Soubor projektu
SampleRulesDB
se zobrazí v textovém editoru. - Povolení analýzy kódu při sestavení v souboru projektu SQL můžete dosáhnout nastavením vlastnosti
RunSqlCodeAnalysis
natrue
. - 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
- 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
- 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říkladC:\NuGetPackages
nebo~/NuGetPackages
:
dotnet nuget add source <local folder path>
- 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.dll
YourSolutionPath\YourProjectPath\bin\Debug
neboYourSolutionPath\YourProjectPath\bin\Release
.
Krok 5.2: Použití vzorových pravidel v databázovém projektu
- Vytvořte nový projekt Microsoft.Build.Sql nebo otevřete existující projekt.
- 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í
- Povolte analýzu kódu pro sestavení v souboru projektu SQL tak, že nastavíte vlastnost
RunSqlCodeAnalysis
natrue
. Balíček SampleRules NuGet se obnoví při sestavení a zahrnutí projektu ve výchozím nastavení. - 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
- 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
- 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říkladC:\NuGetPackages
nebo~/NuGetPackages
:
dotnet nuget add source <local folder path>
- 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.dll
YourSolutionPath\YourProjectPath\bin\Debug
neboYourSolutionPath\YourProjectPath\bin\Release
.
Krok 5.2: Použití vzorových pravidel v databázovém projektu
- Vytvořte nový projekt Microsoft.Build.Sql nebo otevřete existující projekt.
- 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í
- Povolte analýzu kódu během sestavení v souboru projektu SQL nastavením vlastnosti
RunSqlCodeAnalysis
natrue
. Balíček SampleRules NuGet se obnoví při sestavení a zahrnutí projektu ve výchozím nastavení. - 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í.
Související obsah
- analýzy kódu SQL za účelem zlepšení kvality kódu
- Přehled rozšiřitelnosti pravidel analýzy kódu
- Analýza kódu T-SQL za účelem zjištění vad