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.
Şunlar için geçerlidir:SQL Server
Azure SQL Veritabanı
Azure SQL Yönetilen Örneği
Microsoft Fabric'te SQL veritabanı
Veritabanı projenizdeki T-SQL kodunu analiz ettiğinizde, bir veya daha fazla uyarı tasarım sorunları olarak kategorilere ayrılmış olabilir. Aşağıdaki durumlardan kaçınmak için tasarım sorunlarını gidermeniz gerekir:
- Veritabanınızda yapılan sonraki değişiklikler, veritabanınıza bağımlı olan uygulamaları bozabilir.
- Kod beklenen sonucu üretmeyebilir.
- Sql Server'ın gelecek sürümleriyle çalıştırırsanız kod bozulabilir.
Genel olarak, bir tasarım sorununu gizlememeniz gerekir çünkü bu sorun uygulamanızı şimdi veya gelecekte bozabilir.
Sağlanan kurallar aşağıdaki tasarım sorunlarını tanımlar:
- SR0001: Saklı yordamlarda, görünümlerde ve tablo değerli işlevlerde SELECT * kullanmaktan kaçının
- SR0008: @@IDENTITY yerine SCOPE_IDENTITY kullanmayı göz önünde bulundurun
- SR0009: Boyut 1 veya 2 olan değişken uzunluğu türlerini kullanmaktan kaçının
- SR0010: Tabloları veya görünümleri birleştirirken kullanım dışı söz dizimi kullanmaktan kaçının
- SR0013: Çıkış parametresi (parametre) tüm kod yollarında doldurulmuyor
- SR0014: {Type1}'den {Type2} türüne dönüşümde veri kaybı oluşabilir
SR0001: Saklı yordamlarda, görünümlerde ve tablo değerli işlevlerde SELECT * kullanmaktan kaçınmalısınız
Bir tablo veya görünümdeki tüm sütunları seçmek için saklı yordam, görünüm veya tablo değerli işlevde joker karakter kullanırsanız, temel alınan tablo veya görünüm değiştiğinde döndürülen sütunların sayısı veya şekli değişebilir. Sütunun şekli, türünün ve boyutunun bir bileşimidir. Bu değişiklik, saklı yordam, görünüm veya tablo değerli işlevi kullanan uygulamalarda sorunlara neden olabilir çünkü bu kullanıcılar farklı sayıda sütun bekleyebilir.
İhlalleri düzeltme
Joker karakterini sütun adlarının tam listesiyle değiştirerek saklı yordamın, görünümün veya tablo değerli işlevin tüketicilerini şema değişikliklerinden koruyabilirsiniz.
Example
Aşağıdaki örnek önce [Tablo2] adlı bir tabloyu tanımlar ve ardından iki saklı yordamı tanımlar. İlk yordam, SR0001 kuralını ihlal eden bir SELECT *içerir. İkinci işlem, SELECT * atlayarak SELECT deyimindeki sütunları açıkça listeler.
CREATE TABLE [dbo].[Table2]
(
[ID] INT NOT NULL IDENTITY(0, 1),
[c1] INT NOT NULL,
[Comment] NVARCHAR (50)
)
ON [PRIMARY]
CREATE PROCEDURE [dbo].[procWithWarning]
AS
BEGIN
-- Contains code that breaks rule SR0001
SELECT *
FROM [dbo].[Table2]
END
CREATE PROCEDURE [dbo].[procFixed]
AS
BEGIN
-- Explicitly lists the column names in a SELECT statement
SELECT [dbo].[Table2].[ID], [dbo].[Table2].[c1], [dbo].[Table2].[Comment]
FROM [dbo].[Table2]
END
SR0008: @@IDENTITY yerine SCOPE_IDENTITY kullanmayı göz önünde bulundurun
@@IDENTITY genel bir kimlik değeri olduğundan, geçerli kapsamın dışında güncelleştirilmiş ve beklenmeyen bir değer almış olabilir. Çoğaltma tarafından kullanılan iç içe tetikleyiciler dahil olmak üzere diğer tetikleyiciler, mevcut kapsamınızın dışında @@IDENTITY güncelleyebilir.
İhlalleri düzeltme
Bu sorunu çözmek için @@IDENTITY başvurularını kullanıcı deyimi kapsamındaki en son kimlik değerini döndüren SCOPE_IDENTITY ile değiştirmeniz gerekir.
Example
İlk örnekte, @@IDENTITY tabloya veri eklemek için kullanılan bir saklı yordamda kullanılır. Tablo, birleştirme çoğaltması için yayımlanır; bu, yayımlanan tablolara tetikleyiciler ekler. Bu nedenle @@IDENTITY, kullanıcı tablosuna ekleme işlemi yerine bir çoğaltma sistemi tablosuna ekleme işleminden değeri döndürebilir.
Tablonun Sales.Customer kimlik değeri üst sınırı 29483'tür. Tabloya satır eklerseniz, @@IDENTITY ve SCOPE_IDENTITY() farklı değerler döndürür. SCOPE_IDENTITY() kullanıcı tablosuna ekleme işleminden değeri döndürür, ancak @@IDENTITY çoğaltma sistemi tablosuna ekleme işleminden değeri döndürür.
İkinci örnekte, eklenen kimlik değerine erişmek ve uyarıyı çözümlemek için SCOPE_IDENTITY() özelliğini nasıl kullanabileceğiniz gösterilmektedir.
CREATE PROCEDURE [dbo].[ProcedureWithWarning]
@param1 INT,
@param2 NCHAR(1),
@Param3 INT OUTPUT
AS
BEGIN
INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (@param1,@param2);
SELECT @Param3 = @@IDENTITY
END
CREATE PROCEDURE [dbo].[ProcedureFixed]
@param1 INT,
@param2 NCHAR(1),
@param3 INT OUTPUT
AS
BEGIN
INSERT INTO Sales.Customer ([TerritoryID],[CustomerType]) VALUES (@param1,@param2);
SELECT @Param3 = SCOPE_IDENTITY()
END
SR0009: Boyut 1 veya 2 olan değişken uzunluğu türlerini kullanmaktan kaçının
VARCHAR, NVARCHAR ve VARBINARY gibi değişken uzunlukta veri türlerini kullandığınızda, veri türünde depolanan değerin uzunluğunu izlemek için ek bir depolama maliyetine neden olursunuz. Ayrıca, değişken uzunluktaki sütunlar sabit uzunluktaki tüm sütunlardan sonra depolanır ve bu da performans açısından etkilenebilir. VARCHAR gibi bir değişken uzunluğu türü bildirirseniz ancak uzunluk belirtmezseniz de bir uyarı alırsınız. Bu uyarı, belirtilmezse varsayılan uzunluğun 1 olması nedeniyle oluşur.
İhlalleri düzeltme
Türün uzunluğu çok küçük (boyut 1 veya 2) ve tutarlı olacaksa, bunları CHAR, NCHAR ve BINARY gibi sabit uzunlukta bir tür olarak bildirin.
Example
Bu örnekte iki tablonun tanımları gösterilmektedir. İlk tablo, uzunluğu 2 olan değişken uzunlukta bir dize bildirir. İkinci tablo bunun yerine sabit uzunlukta bir dize bildirir ve bu da uyarıyı önler.
CREATE TABLE [dbo].[TableWithWarning]
(
[ID] INT NOT NULL IDENTITY(0, 1),
[c1] INT NOT NULL PRIMARY KEY,
[c2] INT,
[c3] INT,
[SmallString] VARCHAR(2)
)
ON [PRIMARY]
CREATE TABLE [dbo].[FixedTable]
(
[ID] INT NOT NULL IDENTITY(0, 1),
[c1] INT NOT NULL PRIMARY KEY,
[c2] INT,
[c3] INT,
[SmallString] CHAR(2)
)
ON [PRIMARY]
Değişken uzunluğu türlerine ilişkin veriler, sabit uzunluk türleri için verilerden sonra fiziksel olarak depolanır. Bu nedenle, boş olmayan bir tabloda bir sütunu değişkenden sabit uzunluğa değiştirirseniz veri taşımaya neden olursunuz.
SR0010: Tabloları veya görünümleri birleştirirken kullanım dışı söz dizimi kullanmaktan kaçının
Kullanım dışı söz dizimini kullanan birleşimler iki kategoriye ayrılır:
- İç Birleşim: İç birleşim için, birleştirilmekte olan sütunlardaki değerler =, <, >= gibi bir karşılaştırma işleci kullanılarak karşılaştırılır. İç birleşimler yalnızca her tablodan en az bir satır birleştirme koşuluyla eşleşiyorsa satırları döndürür.
- Dış Birleşim: Dış birleşimler, FROM yan tümcesinde belirtilen tablo veya görünümlerden en az birindeki tüm satırları döndürür. Bu satırlar WHERE veya HAVING arama koşullarını karşıladığı sürece. Dış birleşim belirtmek için = veya = kullanırsanız, kullanım dışı söz dizimi kullanırsınız.
İhlalleri düzeltme
İç birleşimdeki bir ihlali düzeltmek için söz dizimini INNER JOIN kullanın.
Dış birleşimdeki bir ihlali düzeltmek için uygun OUTER JOIN söz dizimini kullanın. Aşağıdaki seçeneklere sahipsiniz:
- LEFT OUTER JOIN veya LEFT JOIN (Sol Dış Birleştirme veya Sol Birleştirme)
- SAĞ DIŞ BAĞLAMA veya SAĞ BAĞLAMA
Kullanım dışı söz dizimi ve güncelleştirilmiş söz dizimi örnekleri aşağıdaki örneklerde verilmiştir. Birleştirmeler hakkında daha fazla bilgi için bkz. Joins.
Examples
Altı örnek aşağıdaki seçenekleri gösterir:
- Örnek 1,iç birleşim için kullanım dışı söz dizimini gösterir.
- Örnek 2,Örnek 1'i geçerli söz dizimlerini kullanacak şekilde nasıl güncelleştirebileceğinizi gösterir.
- Örnek 3, sol dış birleşim için artık kullanılmayan söz dizimini gösterir.
- Örnek 4,Örnek 2'yi geçerli söz dizimlerini kullanacak şekilde nasıl güncelleştirebileceğinizi gösterir.
- Örnek 5,sağ dış birleşim için kullanım dışı söz dizimini gösterir.
- Örnek 6,Örnek 5'i geçerli söz dizimlerini kullanacak şekilde nasıl güncelleştirebileceğinizi gösterir.
-- Example 1: Deprecated syntax for an inner join
SELECT [T2].[c3], [T1].[c3]
FROM [dbo].[Table2] T2, [dbo].[Table1] T1
WHERE [T1].[ID] = [T2].[ID]
-- Example 2: Current syntax for an inner join
SELECT [T2].[c3], [T1].[c3]
FROM [dbo].[Table2] AS T2
INNER JOIN [dbo].[Table1] as T1
ON [T2].[ID] = [T2].[ID]
-- Example 3: Deprecated syntax for a left outer join
SELECT [T2].[c3], [T1].[c3]
FROM [dbo].[Table2] T2, [dbo].[Table1] T1
WHERE [T1].[ID] *= [T2].[ID]
-- Example 4: Fixed syntax for a left outer join
SELECT [T2].[c3], [T1].[c3]
FROM [dbo].[Table2] AS T2
LEFT OUTER JOIN [dbo].[Table1] as T1
ON [T2].[ID] = [T2].[ID]
-- Example 5: Deprecated syntax for a right outer join
SELECT [T2].[c3], [T1].[c3]
FROM [dbo].[Table2] T2, [dbo].[Table1] T1
WHERE [T1].[ID] =* [T2].[ID]
-- Example 6: Fixed syntax for a right outer join
SELECT [T2].[c3], [T1].[c3]
FROM [dbo].[Table2] AS T2
RIGHT OUTER JOIN [dbo].[Table1] as T1
ON [T2].[ID] = [T2].[ID]
SR0013: Çıkış parametresi (parametre) tüm kod yollarında doldurulmuyor
Bu kural, saklı yordam veya işlev aracılığıyla çıkış parametresinin bir veya daha fazla kod yolundaki bir değere ayarlanmadığı kodu tanımlar. Bu kural çıkış parametresinin hangi yollarda ayarlanması gerektiğini belirlemez. Birden çok çıkış parametresinde bu sorun varsa, her parametre için bir uyarı görüntülenir.
İhlalleri düzeltme
Bu sorunu iki yoldan biriyle düzeltebilirsiniz. Çıkış parametrelerini yordam gövdesinin başında varsayılan bir değere başlatırsanız bu sorunu en kolay şekilde düzeltebilirsiniz. Bir alternatif olarak, çıkış parametresini parametrenin ayarlanmadığı belirli kod yollarında da bir değere ayarlayabilirsiniz. Ancak, karmaşık bir yordamda yaygın olmayan bir kod yolunu gözden kaçırabilirsiniz.
Important
Yordam bildiriminde bir değer belirtilmesi sorunu CREATE PROC MyProcedure (@param1 INT = 10 OUTPUT) çözmez. Yordam gövdesindeki çıkış parametresine bir değer atamanız gerekir.
Example
Aşağıdaki örnekte iki basit yordam gösterilmektedir. İlk yordam çıkış parametresinin @Sumdeğerini ayarlamaz. İkinci yordam, yordamın @Sum başlangıcında parametresini başlatır ve bu da değerin tüm kod yollarında ayarlanmasını sağlar.
CREATE PROCEDURE [dbo].[procedureHasWarning]
(
@Value1 BIGINT,
@Value2 INT,
@Value3 INT,
@Sum INT OUTPUT
)
AS
BEGIN
-- No initialization of the output parameter
--
-- Additional statements here.
--
RETURN 0;
END
--
CREATE PROCEDURE [dbo].[procedureFixed]
(
@Value1 BIGINT,
@Value2 INT,
@Value3 INT,
@Sum INT OUTPUT
)
AS
BEGIN
-- Initialize the out parameter
SET @Sum = 0;
--
-- Additional statements here
--
RETURN 0;
END
SR0014: {Type1} öğesinden {Type2} türüne veri kaybı oluşabilir
Veri türleri sütunlara, değişkenlere veya parametrelere tutarsız bir şekilde atanmışsa, bu nesneleri içeren Transact-SQL kodu çalıştırıldığında bunlar örtük olarak dönüştürülür. Bu tür bir dönüştürme yalnızca performansı düşürmekle kalmaz, bazı durumlarda küçük veri kaybına da neden olur. Örneğin, WHERE yan tümcesindeki her sütunun dönüştürülmesi gerekiyorsa tablo taraması çalıştırılabilir. Daha da kötüsü, Unicode dizesi farklı bir kod sayfası kullanan bir ASCII dizesine dönüştürülürse veriler kaybolabilir.
Bu kural şunları YAPMAZ:
- Hesaplanan sütunun türünü denetleyin, çünkü tür çalışma zamanına kadar bilinmez.
- CASE deyimi içindeki her şeyi analiz edin. Ayrıca CASE deyiminin dönüş değerini analiz etmez.
- ISNULL çağrısının giriş parametrelerini veya dönüş değerini analiz etme
Bu tabloda SR0014 kuralı kapsamındaki denetimler özetlenmiş:
| Dil yapısı | Kontrol Edilen Nedir? | Example |
|---|---|---|
| Parametrelerin varsayılan değeri | Parametre veri türü |
|
| CREATE INDEX koşulu | Koşul Boole değeridir |
|
| SOL veya SAĞ işlevlerinin bağımsız değişkenleri | Dize bağımsız değişkeni türü ve uzunluğu |
|
| CAST ve CONVERT işlevlerinin bağımsız değişkenleri | İfade ve tipler geçerli |
|
| SET deyimi | Sol ve sağ tarafta uyumlu tipler bulunuyor |
|
| IF ifadesi şarta bağlı | Koşul Boole değeridir |
|
| WHILE deyimi koşulu | Koşul Boole değeridir |
|
| INSERT deyimi | Değerler ve sütunlar doğru |
|
| SELECT WHERE önermesi | Koşul Boole değeridir |
|
| SELECT TOP ifadesi | İfade bir Tamsayı veya Float türüdür |
|
| UPDATE deyimi | İfade ve sütun uyumlu türlere sahiptir |
|
| UPDATE koşulu | Koşul Boole değeridir |
|
| UPDATE TOP ifadesi | İfade bir Tamsayı veya Float türüdür |
|
| KOŞUL İFADESİNİ SİL | Koşul Boole değeridir |
|
| DELETE TOP ifadesi | İfade bir Tamsayı veya Float türüdür |
|
| DECLARE değişken tanımlama | İlk değer ve veri türü uyumludur |
|
| EXECUTE deyimi bağımsız değişkenleri ve dönüş türü | Parametreler ve bağımsız değişkenler |
|
| RETURN deyimi | RETURN ifadesi uyumlu bir veri türüne sahip |
|
| MERGE deyimi koşulları | Koşul Boole değeridir |
|
İhlalleri düzeltme
Veri türlerini tutarlı bir şekilde atayarak ve gerektiğinde türleri açıkça dönüştürerek bu sorunlardan kaçınabilir ve çözebilirsiniz. Veri türlerini açıkça dönüştürme hakkında daha fazla bilgi için Microsoft Web sitesindeki şu sayfaya bakın: CAST ve CONVERT (Transact-SQL).
Example
Örnekte, iki saklı prosedür ile bir tabloya veri ekleme işlemi gösterilmektedir. İlk yordam olan procWithWarning, bir veri türünün örtük olarak dönüştürülmesiyle sonuçlanır. İkinci yordam olan procFixed, performansı en üst düzeye çıkarmak ve tüm verileri korumak için nasıl açık dönüştürme ekleyebileceğinizi gösterir.
CREATE TABLE [dbo].[Table2]
(
[ID] INT NOT NULL IDENTITY(0, 1),
[c1] INT NOT NULL,
[c2] INT NOT NULL,
[c3] BIGINT NOT NULL,
[Comment] VARCHAR (25)
)
ON [PRIMARY]
CREATE PROCEDURE [dbo].[procWithWarning]
(
@Value1 INT,
@Value2 INT,
@Value3 BIGINT,
@Comment CHAR(30)
)
AS
BEGIN
INSERT INTO [Table2] ([c1], [c2], [c3], Comment)
VALUES (@Value1, @Value2, @Value3, @Comment)
END
CREATE PROCEDURE [dbo].[procFixed]
(
@Value1 INT,
@Value2 INT,
@Value3 BIGINT,
@Comment CHAR(10)
)
AS
BEGIN
INSERT INTO [Table2] ([c1], [c2], [c3], Comment)
VALUES (@Value1, @Value2, @Value3, CAST(@Comment AS VARCHAR(25)))
END
İlgili içerik
- Kod kalitesini geliştirmek için SQL kod analizini
- T-SQL adlandırma sorunları
- T-SQL performans sorunları
- hataları bulmak için T-SQL kodunu analiz