Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu kılavuzda SQL Server kod çözümleme kuralı oluşturmak için kullanılan adımlar gösterilmektedir. Bu kılavuzda oluşturulan kural, saklı yordamlarda, tetikleyicilerde ve işlevlerde WAITFOR DELAY
komutlarından kaçınmak için kullanılır.
Bu kılavuzda, aşağıdaki adımları kullanarak statik kod analizi Transact-SQL için özel bir kural oluşturacaksınız:
- Bir sınıf kitaplığı projesi oluşturun, bu proje için imzalamayı etkinleştirin ve gerekli başvuruları ekleyin.
- İki yardımcı C# sınıfı oluşturun.
- C# özel kural sınıfı oluşturun.
- Sınıf kitaplığı projesini oluşturun.
- Yeni kod analizi kuralını yükleyin ve test edin.
Visual Studio (SQL Server Veri Araçları) yönergeleri dışında, kılavuz SDK stili SQL projelerine odaklanır.
Önkoşullar
Bu kılavuzu tamamlamak için aşağıdaki bileşenlere ihtiyacınız vardır:
- SQL Server Veri Araçları'nı içeren ve C# .NET Framework geliştirmesini destekleyen bir Visual Studio sürümü yüklü.
- SQL Server nesneleri içeren bir SQL Server projesi.
- Veritabanı projesini dağıtabileceğiniz bir SQL Server örneği.
Bu kılavuz, SQL Server Veri Araçları'nın SQL Server özelliklerini zaten bilen kullanıcılara yöneliktir. Sınıf kitaplığı oluşturma, NuGet paketleri ekleme ve bir sınıfa kod eklemek için kod düzenleyicisini kullanma gibi Visual Studio kavramları hakkında bilgi sahibi olmanız gerekir.
Uyarı
SDK stili SQL Server Veri Araçları'nın önizleme sınırlamaları nedeniyle, bu kılavuzu tamamlamak için birden çok Visual Studio yüklemesi gerekir. İlk yükleme sınıf kitaplığı projesini oluşturmak için, ikinci yükleme ise SDK stili sql veritabanı projesini oluşturmak için gereklidir.
- .NET 8 SDK
- Visual Studio 2022 Community, Professional veya Enterprise sürümü
- Visual Studio 2022'de yüklenen SDK tarzı (önizleme) SQL Server Veri Araçları
- Visual Studio'nun C# .NET geliştirmesini destekleyen bir sürümü yüklü.
- SQL Server nesneleri içeren bir SQL Server projesi.
Bu kılavuz, SQL Server Veri Araçları'nın SQL Server özelliklerini zaten bilen kullanıcılara yöneliktir. Sınıf kitaplığı oluşturma, NuGet paketleri ekleme ve bir sınıfa kod eklemek için kod düzenleyicisini kullanma gibi Visual Studio kavramları hakkında bilgi sahibi olmanız gerekir.
- SQL Veritabanı Projeleri uzantısını içeren Visual Studio Code'un yüklü bir sürümü.
- SQL nesneleri içeren bir SQL veritabanı projesi.
- .NET 8 SDK
- Önerilen: VS Code için C# Dev Kit uzantısı
Bu kılavuz, Visual Studio Code'daki SQL Veritabanı Projeleri uzantısını zaten bilen kullanıcılara yöneliktir. Sınıf kitaplığı oluşturma, paket ekleme ve kodu düzenlemek için kod düzenleyicisini kullanma gibi geliştirme kavramları hakkında bilgi sahibi olmanız gerekir.
- Visual Studio Code'daki dosya düzenleyicisi gibi bir metin düzenleyicisi.
- SQL nesneleri içeren bir SQL veritabanı projesi.
- .NET 8 SDK
Bu kılavuz, SQL projelerini zaten bilen kullanıcılara yöneliktir. Sınıf kitaplığı oluşturma, paket ekleme ve kodu düzenlemek için kod düzenleyicisini kullanma gibi geliştirme kavramları hakkında bilgi sahibi olmanız gerekir.
1. Adım: Sınıf kitaplığı projesi oluşturma
İlk olarak bir sınıf kitaplığı oluşturun. Sınıf kitaplığı projesi oluşturmak için:
adlı
SampleRules
bir C# (.NET Framework) sınıf kitaplığı projesi oluşturun.Dosyayı
Class1.cs
olarakAvoidWaitForDelayRule.cs
yeniden adlandırın.Çözüm Gezgini'nde proje düğümüne sağ tıklayın ve ardından Ekle'yi ve ardından Başvuru'ya tıklayın.
Assemblies\Frameworks sekmesinde öğesini seçin
System.ComponentModel.Composition
.Çözüm Gezgini'nde proje düğümüne sağ tıklayın ve ardından NuGet Paketlerini Yönet'i seçin. NuGet paketini bulun ve yükleyin
Microsoft.SqlServer.DacFx
. Seçilen sürüm (örneğin162.2.111
), Visual Studio 2022 ile olmalıdır162.x.x
.
Ardından, kural tarafından kullanılacak destekleyici sınıflar ekleyin.
İlk olarak bir sınıf kitaplığı oluşturun. Sınıf kitaplığı projesi oluşturmak için:
adlı
SampleRules
bir C# (.NET Framework) sınıf kitaplığı projesi oluşturun.Dosyayı
Class1.cs
olarakAvoidWaitForDelayRule.cs
yeniden adlandırın.Çözüm Gezgini'nde proje düğümüne sağ tıklayın ve ardından Ekle'yi ve ardından Başvuru'ya tıklayın.
Assemblies\Frameworks sekmesinde öğesini seçin
System.ComponentModel.Composition
.Çözüm Gezgini'nde proje düğümüne sağ tıklayın ve ardından NuGet Paketlerini Yönet'i seçin. NuGet paketini bulun ve yükleyin
Microsoft.SqlServer.DacFx
. Seçilen sürüm (örneğin162.2.111
), Visual Studio 2022 ile olmalıdır162.x.x
.
Ardından, kural tarafından kullanılacak destekleyici sınıflar ekleyin.
Visual Studio Code'u başlatın ve projeyi oluşturmak istediğiniz klasörü açın.
Görünüm menüsünü ve ardından Terminal'i seçerek Visual Studio Code'da bir Terminal penceresi açın.
Terminalde, yeni bir çözüm ve proje oluşturmak için aşağıdaki komutları girin:
dotnet new sln dotnet new classlib -n SampleRules -o SampleRules dotnet sln add SampleRules/SampleRules.csproj
Dizine
SampleRules
geçincd SampleRules
Gerekli NuGet paketini ekleyin:
dotnet add package Microsoft.SqlServer.DacFx
Ardından, kural tarafından kullanılacak destekleyici sınıflar ekleyin.
Bir komut istemi veya terminal penceresi açın ve projeyi oluşturmak istediğiniz klasöre gidin.
Terminalde, yeni bir çözüm ve proje oluşturmak için aşağıdaki komutları girin:
dotnet new sln dotnet new classlib -n SampleRules -o SampleRules dotnet sln add SampleRules/SampleRules.csproj
Klasöre
SampleRules
geçiş yapın.cd SampleRules
Gerekli NuGet paketini ekleyin:
dotnet add package Microsoft.SqlServer.DacFx
2. Adım: Özel kural yardımcı sınıfları oluşturma
Kuralın kendisi için sınıfı oluşturmadan önce, projeye bir ziyaretçi sınıfı ve öznitelik sınıfı ekleyin. Bu sınıflar daha fazla özel kural oluşturmak için yararlı olabilir.
2.1. Adım: WaitForDelayVisitor sınıfını tanımlama
Tanımlamanız gereken ilk sınıf, TSqlConcreteFragmentVisitor'dan türetilen sınıfıdırWaitForDelayVisitor
. Bu sınıf modeldeki WAITFOR DELAY
deyimlere erişim sağlar. Ziyaretçi sınıfları SQL Server tarafından sağlanan ScriptDom API'lerini kullanır. Bu API'de Transact-SQL kodu soyut söz dizimi ağacı (AST) olarak temsil edilir ve deyimler gibi WAITFOR DELAY
belirli söz dizimi nesnelerini bulmak istediğinizde ziyaretçi sınıfları yararlı olabilir. Belirli bir nesne özelliği veya ilişkisiyle ilişkilendirilmediğinden, bu deyimleri nesne modelini kullanarak bulmak zor olabilir, ancak bunları ziyaretçi desenini ve ScriptDom API'sini kullanarak bulabilirsiniz.
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Sınıf Ekle'yi seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna
WaitForDelayVisitor.cs
yazın ve Ekle düğmesini seçin. DosyaWaitForDelayVisitor.cs
, Çözüm Gezgini'nde projeye eklenir.
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Sınıf Ekle'yi seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna
WaitForDelayVisitor.cs
yazın ve Ekle düğmesini seçin. DosyaWaitForDelayVisitor.cs
, Çözüm Gezgini'nde projeye eklenir.
Visual Studio Code'da Gezgin görünümünü açın.
klasöründe adlı
WaitForDelayVisitor.cs
SampleRules
yeni bir dosya oluşturun.
-
SampleRules
dizinine gidin. -
WaitForDelayVisitor.cs
adlı yeni bir dosya oluşturun.
WaitForDelayVisitor.cs
Dosyayı açın ve içeriği aşağıdaki kodla eşleşecek şekilde güncelleştirin:using System.Collections.Generic; using Microsoft.SqlServer.TransactSql.ScriptDom; namespace SampleRules { class WaitForDelayVisitor {} }
Sınıf bildiriminde, erişim değiştiricisini dahili olarak değiştirin ve
TSqlConcreteFragmentVisitor
sınıfından türetin.internal class WaitForDelayVisitor : TSqlConcreteFragmentVisitor {}
List üye değişkenini tanımlamak için aşağıdaki kodu ekleyin:
public IList<WaitForStatement> WaitForDelayStatements { get; private set; }
Aşağıdaki kodu ekleyerek sınıf oluşturucuyu tanımlayın:
public WaitForDelayVisitor() { WaitForDelayStatements = new List<WaitForStatement>(); }
ExplicitVisit
Aşağıdaki kodu ekleyerek yöntemini geçersiz kılın:public override void ExplicitVisit(WaitForStatement node) { // We are only interested in WAITFOR DELAY occurrences if (node.WaitForOption == WaitForOption.Delay) WaitForDelayStatements.Add(node); }
Bu yöntem modeldeki
WAITFOR
deyimleri ziyaret eder ve deyim listesineDELAY
WAITFOR DELAY
seçeneği belirtilen deyimleri ekler. Başvurulan anahtar sınıfı WaitForStatement'tır.Dosya menüsünde Kaydetseçin.
2.2. Adım: Kaynak dosyası ve üç kaynak dizesi ekleme
Ardından kural adını, kural açıklamasını ve kuralın kural yapılandırma arabiriminde görüneceği kategoriyi tanımlayan bir kaynak dosyası ekleyin.
Çözüm Gezgini'da projeyi seçin
SampleRules
. Proje menüsünde Ekle'yi ve ardından Yeni Öğe'yi seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir.Yüklü Şablonlar listesinde Genel'i seçin. Ayrıntılar bölmesinde Kaynaklar Dosyası'nı seçin.
Ad alanına yazın
RuleResources.resx
. Kaynak düzenleyicisi görünür, ancak herhangi bir kaynak tanımlanmamıştır.Dört kaynak dizesini aşağıdaki gibi tanımlayın:
İsim Değer 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}.
Dosya menüsünde Kuralı KaydetResources.resx'i seçin.
Çözüm Gezgini'da projeyi seçin
SampleRules
. Proje menüsünde Ekle'yi ve ardından Yeni Öğe'yi seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir.Yüklü Şablonlar listesinde Genel'i seçin. Ayrıntılar bölmesinde Kaynaklar Dosyası'nı seçin.
Ad alanına yazın
RuleResources.resx
. Kaynak düzenleyicisi görünür ve tanımlı kaynak yoktur.Dört kaynak dizesini aşağıdaki gibi tanımlayın:
İsim Değer 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}.
Dosya menüsünde Kuralı KaydetResources.resx'i seçin.
dizininde
SampleRules
adlıRuleResources.resx
yeni bir dosya oluşturun.RuleResources.resx
Dosyayı açın ve aşağıdaki kodu ekleyin:<?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>
RuleResources.resx
dosyasını kaydedin.SampleRules.csproj
Dosyayı açın ve aşağıdaki kodu ekleyerek projedeki kaynak içeriğini güncelleştirin ve ekleyin:<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>
SampleRules.csproj
dosyasını kaydedin.
dizininde
SampleRules
adlıRuleResources.resx
yeni bir dosya oluşturun.RuleResources.resx
Dosyayı açın ve aşağıdaki kodu ekleyin:<?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>
RuleResources.resx
dosyasını kaydedin.SampleRules.csproj
Dosyayı açın ve aşağıdaki kodu ekleyerek projedeki kaynak içeriğini güncelleştirin ve ekleyin:<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>
SampleRules.csproj
dosyasını kaydedin.
2.3. Adım: LocalizedExportCodeAnalysisRuleAttribute sınıfını tanımlama
İkinci sınıf: LocalizedExportCodeAnalysisRuleAttribute.cs
. Bu, çerçeve tarafından sağlanan yerleşik Microsoft.SqlServer.Dac.CodeAnalysis.ExportCodeAnalysisRuleAttribute
bir uzantıdır ve bir kaynak dosyasından kuralınız tarafından kullanılan ve Description
okumasını DisplayName
destekler. Kurallarınızı birden çok dilde kullanmayı düşünüyorsanız, bu yararlı bir sınıftır.
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Sınıf Ekle'yi seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna önce yazın
LocalizedExportCodeAnalysisRuleAttribute.cs
, sonra Ekle düğmesini seçin. Dosya, Çözüm Gezgini'nde projeye eklenir.
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Sınıf Ekle'yi seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna
LocalizedExportCodeAnalysisRuleAttribute.cs
yazın ve ardından Ekle düğmesini seçin. Dosya, Çözüm Gezgini'nde projeye eklenir.
-
SampleRules
Visual Studio Code'da Gezgin görünümünde dizine gidin. -
LocalizedExportCodeAnalysisRuleAttribute.cs
adlı yeni bir dosya oluşturun.
-
SampleRules
dizinine gidin. -
LocalizedExportCodeAnalysisRuleAttribute.cs
adlı yeni bir dosya oluşturun.
Dosyayı açın ve içeriği aşağıdaki kodla eşleşecek şekilde güncelleştirin:
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; } } } }
2.4. Adım: SampleConstants sınıfını tanımlama
Ardından, kullanıcı arabiriminde kuralınızla ilgili bilgileri görüntülemek için Visual Studio tarafından kullanılan kaynak dosyasındaki kaynaklara başvuran bir sınıf tanımlayın.
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Ekle'yi ve ardından Sınıf'ı seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna yazın ve Ekle düğmesini seçin. Dosya
SampleRuleConstants.cs
, Çözüm Gezgini'nde projeye eklenir.
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Ekle'yi ve ardından Sınıf'ı seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna
SampleRuleConstants.cs
yazın ve Ekle düğmesini seçin. DosyaSampleRuleConstants.cs
, Çözüm Gezgini'nde projeye eklenir.
-
SampleRules
Visual Studio Code'da Gezgin görünümünde ilgili dizine gidin. -
SampleRuleConstants.cs
adlı yeni bir dosya oluşturun.
-
SampleRules
dizinine gidin. -
SampleRuleConstants.cs
adlı yeni bir dosya oluşturun.
SampleRuleConstants.cs
dosyasını açın ve aşağıdaki using deyimlerini dosyaya ekleyin: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"; } }
Dosya menüsünde Kaydetseçin.
3. Adım: Özel kural sınıfı oluşturma
Özel kod çözümleme kuralının kullanacağı yardımcı sınıfları ekledikten sonra, özel bir kural sınıfı oluşturun ve adını verin AvoidWaitForDelayRule
.
AvoidWaitForDelayRule
özel kural, saklı yordamlarda, tetikleyicilerde ve işlevlerde WAITFOR DELAY
deyimlerinden kaçınmalarına yardımcı olmak için veritabanı geliştiricileri tarafından kullanılacaktır.
3.1. Adım: AvoidWaitForDelayRule sınıfını oluşturma
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Ekle'yi ve ardından Sınıf'ı seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna yazın
AvoidWaitForDelayRule.cs
ve Ekle'yi seçin. DosyaAvoidWaitForDelayRule.cs
, Çözüm Gezgini'nde projeye eklenir.
Çözüm Gezgini'da projeyi seçin
SampleRules
.Proje menüsünde Ekle'yi ve ardından Sınıf'ı seçin. Yeni Öğe Ekle iletişim kutusu görüntülenir. Ad metin kutusuna yazın
AvoidWaitForDelayRule.cs
ve Ekle'yi seçin. DosyaAvoidWaitForDelayRule.cs
, Çözüm Gezgini'nde projeye eklenir.
- Visual Studio Code'da Gezgin görünümünde
SampleRules
dizinine gidin. -
AvoidWaitForDelayRule.cs
adlı yeni bir dosya oluşturun.
-
SampleRules
dizinine gidin. -
AvoidWaitForDelayRule.cs
adlı yeni bir dosya oluşturun.
AvoidWaitForDelayRule.cs
dosyasını açın ve aşağıdaki using deyimlerini dosyaya ekleyin: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 {} }
Sınıf bildiriminde
AvoidWaitForDelayRule
erişim değiştiricisini public olarak ayarlayın./// <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
AvoidWaitForDelayRule
sınıfınıMicrosoft.SqlServer.Dac.CodeAnalysis.SqlCodeAnalysisRule
temel sınıftan türetin.public sealed class AvoidWaitForDelayRule : SqlCodeAnalysisRule
öğesini
LocalizedExportCodeAnalysisRuleAttribute
sınıfınıza ekleyin.LocalizedExportCodeAnalysisRuleAttribute
kod analizi hizmetinin özel kod çözümleme kurallarını bulmasına izin verir. Kod analizinde yalnızca birExportCodeAnalysisRuleAttribute
(veya bundan devralan bir öznitelik) ile işaretlenmiş sınıflar kullanılabilir.LocalizedExportCodeAnalysisRuleAttribute
, hizmet tarafından kullanılan bazı gerekli meta verileri sağlar. Bu kural için benzersiz bir kimlik, Visual Studio kullanıcı arabiriminde gösterilen bir görünen ad ve sorunları tanımlarken kuralınız tarafından kullanılabilecek birDescription
ad içerir.[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"; }
RuleScope özelliği, bu kural belirli öğeleri analiz ettiğinden
Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleScope.Element
olmalıdır. Kural, modeldeki eşleşen her öğe için bir kez çağrılır. Modelin tamamınıMicrosoft.SqlServer.Dac.CodeAnalysis.SqlRuleScope.Model
analiz etmek isterseniz bunun yerine kullanılabilir.Microsoft.SqlServer.Dac.CodeAnalysis.SqlAnalysisRule.SupportedElementTypes
öğesini ayarlayan bir oluşturucu ekleyin. Bu, öğe düzeyindeki kurallar için gereklidir. Bu kuralın uygulandığı öğe türlerini tanımlar. Bu durumda kural saklı yordamlara, tetikleyicilere ve işlevlere uygulanır. sınıfı,Microsoft.SqlServer.Dac.Model.ModelSchema
çözümlenebilecek tüm kullanılabilir öğe türlerini listeler.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 }; }
Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleExecutionContext
'yi giriş parametreleri olarak kullananMicrosoft.SqlServer.Dac.CodeAnalysis.SqlAnalysisRule.Analyze
(Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleExecutionContext)
yöntemine bir geçersiz kılma ekleyin. Bu yöntem olası sorunların listesini döndürür.yöntemi bağlam parametresinden ,
Microsoft.SqlServer.Dac.Model.TSqlObject
ve TSqlFragment değerlerini alırMicrosoft.SqlServer.Dac.Model.TSqlModel
. SınıfıWaitForDelayVisitor
daha sonra modeldeki tümWAITFOR DELAY
deyimlerin listesini almak için kullanılır.Bu listedeki her WaitForStatement için bir
Microsoft.SqlServer.Dac.CodeAnalysis.SqlRuleProblem
oluşturulur./// <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); }
Dosya menüsünde Kaydet'i seçin.
4. Adım: Sınıf kitaplığını oluşturma
- Proje menüsünde SampleRules Özellikleri'ni seçin.
- İmzalama sekmesini seçin.
- Derlemeyi imzala seçeneğine tıklayın.
- Güçlü ad anahtarı dosyasında<Yeni>'yi seçin.
-
Tanımlayıcı Ad Anahtarı Oluştur iletişim kutusunda, Anahtar dosya adı alanına yazın
MyRefKey
. - (isteğe bağlı) Tanımlayıcı ad anahtarı dosyanız için bir parola belirtebilirsiniz.
- Tamam'ı seçin.
- Dosya menüsünde Tümünü Kaydet seçeneğiniseçin.
- Derle menüsünde Çözüm Derle'yi seçin.
- Proje menüsünde SampleRules Özellikleri'ni seçin.
- İmzalama sekmesini seçin.
- Derlemeyi imzala'ya tıklayın.
- Güçlü bir ad anahtarı dosyası seçin ve <Yeni> seçeneğine tıklayın.
-
Tanımlayıcı Ad Anahtarı Oluştur iletişim kutusunda, Anahtar dosya adı alanına yazın
MyRefKey
. - (isteğe bağlı) Tanımlayıcı ad anahtarı dosyanız için bir parola belirtebilirsiniz.
- Tamam'ı seçin.
- Dosya menüsünde Tümünü Kaydet seçeneğiniseçin.
- Derle menüsünde "Çözümü Derle"yi seçin.
Görünüm menüsünü ve ardından Terminal'i seçerek Visual Studio Code'da Terminal penceresini açın.
Terminalde, projeyi oluşturmak için aşağıdaki komutu girin:
dotnet build /p:Configuration=Release
SampleRules
dizinine gidin.Projeyi oluşturmak için aşağıdaki komutu çalıştırın:
dotnet build /p:Configuration=Release
5. Adım: Yeni kod analizi kuralını yükleme ve test edin
Ardından, bir SQL veritabanı projesi oluşturduğunuzda yüklensin diye derlemeyi kurmanız gerekir.
Visual Studio ile özgün bir SQL projesi oluşturduğunuzda çalışacak bir kural yüklemek için derlemeyi ve ilişkili .pdb
dosyayı Uzantılar klasörüne kopyalamanız gerekir.
Adım 5.1: SampleRules derlemesini yükleme
- Ardından, derleme bilgilerini Uzantılar dizinine kopyalayın. Visual Studio başladığında, dizin ve alt dizinlerdeki
<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
uzantıları tanımlar ve bunları kullanıma hazır hale getirir. Visual Studio 2022 için genellikle<Visual Studio Install Dir>
şeklindedirC:\Program Files\Microsoft Visual Studio\2022\Enterprise
.Enterprise
öğesini, yüklediğiniz Visual Studio sürümüne bağlı olarakProfessional
veyaCommunity
ile değiştirin. -
SampleRules.dll
Derleme dosyasını çıkış dizininden dizinine<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
kopyalayın. Varsayılan olarak, derlenmiş.dll
dosyanızın yoluYourSolutionPath\YourProjectPath\bin\Debug
veyaYourSolutionPath\YourProjectPath\bin\Release
şeklindedir.
Uyarı
Extensions
dizinini oluşturmanız gerekebilir.
Kuralınız artık yüklü olmalıdır ve Visual Studio'yu yeniden başlattıktan sonra görünür. Ardından, yeni bir Visual Studio oturumu başlatın ve bir veritabanı projesi oluşturun.
5.2. Adım: Yeni bir Visual Studio oturumu başlatma ve veritabanı projesi oluşturma
- Visual Studio'nun ikinci oturumını başlatın.
- Dosya>Yeni>Proje’yi seçin.
- Yeni Proje iletişim kutusunda SQL Server Veritabanı Projesi'ni bulun ve seçin.
-
Ad metin kutusuna yazın
SampleRulesDB
ve Tamam'ı seçin.
5.3. Adım: AvoidWaitForRule Kod Analizi kuralını etkinleştirme
- Çözüm Gezgini'da projeyi seçin
SampleRulesDB
. -
Proje menüsünde Özellikler'i seçin.
SampleRulesDB
Özellikler sayfası görüntülenir. -
Kod Analizi'ne tıklayın. adlı
RuleSamples.CategorySamples
yeni bir kategori görmeniz gerekir. - Genişlet
RuleSamples.CategorySamples
. ifadesini görmenizSR1004: Avoid WAITFOR DELAY statement in stored procedures, triggers, and functions
gerekir. - Kural adının yanındaki onay kutusunu ve Derlemede kod analizini etkinleştir onay kutusunu seçerek bu kuralı etkinleştirin. Kod analizini etkinleştirme hakkında daha fazla bilgi için Kod analizine genel bakış bölümüne bakın.
- Proje derleme eylemi kullanıldığında kural yürütülür ve bulunan tüm
WAITFOR DELAY
deyimler uyarı olarak bildirilir.
Visual Studio ile özgün bir SQL projesi oluşturduğunuzda çalışacak bir kural yüklemek için derlemeyi ve ilişkili .pdb
dosyayı Uzantılar klasörüne kopyalamanız gerekir.
Adım 5.1: SampleRules derlemesini yükleme
- Ardından, derleme bilgilerini Uzantılar dizinine kopyalayın. Visual Studio başladığında, dizin ve alt dizinlerdeki
<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
uzantıları tanımlar ve bunları kullanıma hazır hale getirir. Visual Studio 2022 için genellikle<Visual Studio Install Dir>
şeklindedirC:\Program Files\Microsoft Visual Studio\2022\Enterprise
. Visual Studio sürümünüze bağlı olarakEnterprise
öğesiniProfessional
veyaCommunity
ile değiştirin. -
SampleRules.dll
Derleme dosyasını çıkış dizininden dizinine<Visual Studio Install Dir>\Common7\IDE\Extensions\Microsoft\SQLDB\DAC\Extensions
kopyalayın. Varsayılan olarak, derlenmiş.dll
dosyanızın yoluYourSolutionPath\YourProjectPath\bin\Debug
veyaYourSolutionPath\YourProjectPath\bin\Release
'dir.
Uyarı
Extensions
dizinini oluşturmanız gerekebilir.
Kuralınız artık yüklü olmalıdır ve Visual Studio'yu yeniden başlattıktan sonra görünür. Ardından, yeni bir Visual Studio oturumu başlatın ve bir veritabanı projesi oluşturun.
5.2. Adım: Yeni bir Visual Studio oturumu başlatma ve veritabanı projesi oluşturma
- Visual Studio'nun ikinci oturumını başlatın.
- Dosya>Yeni>Proje’yi seçin.
- Yeni Proje iletişim kutusunda SQL Server Veritabanı Projesi, SDK stili (önizleme) öğesini bulun ve seçin.
-
Ad metin kutusuna yazın
SampleRulesDB
ve Tamam'ı seçin.
5.3. Adım: AvoidWaitForRule Kod Analizi kuralını etkinleştirme
- Çözüm Gezgini'da projeyi seçin
SampleRulesDB
. - Proje dosyasını açmak için proje düğümüne çift tıklayın. Proje
SampleRulesDB
dosyası bir metin düzenleyicisinde görüntülenir. - SQL proje dosyasındaki derlemede kod analizini etkinleştirmek için
RunSqlCodeAnalysis
özelliğinitrue
olarak ayarlayın. - Proje derleme eylemi kullanıldığında kural yürütülür ve bulunan tüm
WAITFOR DELAY
deyimler uyarı olarak bildirilir.
5.1. Adım: SampleRules derlemesini yerel bir NuGet kaynağına yerleştirme
- NuGet paketleri için yerel bir kaynağınız yoksa yerel makinenize yerel test için NuGet paketlerini depolamak üzere bir klasör ekleyin. Aşağıdaki komutu çalıştırarak geçerli NuGet kaynaklarınızı de kontrol edebilirsiniz:
dotnet nuget list source
- Yerel bir kaynak listelenmemişse,
<local folder path>
öğesiniC:\NuGetPackages
veya~/NuGetPackages
gibi yerel klasörünüzün yoluyla değiştirerek aşağıdaki komutu kullanarak bir kaynak ekleyebilirsiniz:
dotnet nuget add source <local folder path>
-
SampleRules.dll
Derleme dosyasını çıkış dizininden yerel NuGet kaynak dizinine kopyalayın. Varsayılan olarak, derlenmiş.dll
dosyanızın yoluYourSolutionPath\YourProjectPath\bin\Debug
veyaYourSolutionPath\YourProjectPath\bin\Release
şeklindedir.
5.2. Adım: Veritabanı projesinde SampleRules kullanma
- Yeni bir Microsoft.Build.Sql projesi oluşturun veya var olan bir projeyi açın.
- Proje dosyasındaki SampleRules NuGet paketine bir paket başvurusu ekleyin. Aşağıdaki örnek,
.sqlproj
dosyasına SampleRules NuGet paketine nasıl başvuru ekleneceğini göstermektedir.
<ItemGroup>
<PackageReference Include="SampleRules" Version="1.0.0" />
</ItemGroup>
5.3. Adım: Derlemede kod analizini etkinleştirme
-
Derlemede kod analizini etkinleştirmek için SQL proje dosyasındaki
RunSqlCodeAnalysis
özelliğinitrue
olarak ayarlayın. Proje oluşturulduğunda ve varsayılan olarak dahil edildiğinde SampleRules NuGet paketi geri yüklenir. - Proje derleme eylemi kullanıldığında kural yürütülür ve bulunan tüm
WAITFOR DELAY
deyimler uyarı olarak bildirilir.
5.1. Adım: SampleRules derlemesini yerel bir NuGet kaynağına yerleştirme
- NuGet paketleri için yerel bir kaynağınız yoksa yerel makinenize yerel test için NuGet paketlerini depolamak üzere bir klasör ekleyin. Aşağıdaki komutu çalıştırarak geçerli NuGet kaynaklarınızı de kontrol edebilirsiniz:
dotnet nuget list source
- Bir yerel kaynak listelenmiyorsa, aşağıdaki komutu kullanarak, yerel klasörünüzün yolunu belirtin, örneğin
<local folder path>
,C:\NuGetPackages
veya~/NuGetPackages
, ve bir yerel kaynak ekleyebilirsiniz:
dotnet nuget add source <local folder path>
-
SampleRules.dll
Derleme dosyasını çıkış dizininden yerel NuGet kaynak dizinine kopyalayın. Varsayılan olarak, derlenmiş.dll
dosyanızın yoluYourSolutionPath\YourProjectPath\bin\Debug
veyaYourSolutionPath\YourProjectPath\bin\Release
'dir.
5.2. Adım: Veritabanı projesinde SampleRules kullanma
- Yeni bir Microsoft.Build.Sql projesi oluşturun veya var olan bir projeyi açın.
- Proje dosyasındaki SampleRules NuGet paketine bir paket başvurusu ekleyin. Aşağıdaki örnek,
.sqlproj
dosyasına SampleRules NuGet paketine nasıl başvuru ekleneceğini göstermektedir:
<ItemGroup>
<PackageReference Include="SampleRules" Version="1.0.0" />
</ItemGroup>
5.3. Adım: Derlemede kod analizini etkinleştirme
-
Derlemede kod analizini SQL proje dosyasında etkinleştirmek için
RunSqlCodeAnalysis
özelliğinitrue
olarak ayarlayın. Proje oluşturulduğunda ve varsayılan olarak dahil edildiğinde SampleRules NuGet paketi geri yüklenir. - Proje derleme eylemi kullanıldığında kural yürütülür ve bulunan tüm
WAITFOR DELAY
deyimler uyarı olarak bildirilir.
İlgili içerik
- Kod kalitesini geliştirmek için SQL kod analizini
- Kod analizi kuralları genişletilebilirliğine genel bakış
- hataları bulmak için T-SQL kodunu analiz