Czy zastanawialiście się kiedyś jak dodawać parametry do SqlCommand? Klasa ta zawiera pole Parameters typy SqlParameterCollection, na którym możemy wykonać między innymi metodę AddWithValue(string, object). W internecie jak i w dokumentacji w nazwach parametrów na początku jest zawsze użyty znak “@”.
Przy okazji jednego z projektów musiałem odpowiedzieć sobie na pytanie: Czy muszę zadbać o “@” przy nazwie parametru? Nie zastanawiając się długo postanowiłem, zgodnie duchem empiryzmu, sprawdzić co się stanie w poszczególnych sytuacjach.
Baza danych.
Dla testów mała baza danych z jedną procedurą pobierającą dwa parametry:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | CREATE DATABASE SqlCmdParametersTest USE [SqlCmdParametersTest] CREATE PROCEDURE [dbo].[spTest] @Param1 INT, @Param2 INT AS BEGIN SET NOCOUNT ON; SELECT @Param1 Col1, @Param2 Col2END GO -- TEST EXEC [dbo].[spTest] 1, 2 EXEC [dbo].[spTest] @Param1=1, @Param2=2 EXEC [dbo].[spTest] @Param2=1, @Param1=2 |
Aplikacja testowa
Teraz nie pozostaje nic innego jak przygotować małą aplikację konsolową, która skorzysta z tej procedury. Wiadomo, że podstawowym sposobem dodawania parametrów jest użycie “@” na początku nazwy, zatem będzie to pierwszy sposób użycia. Jako drugi przypadek weźmiemy parametr bez tego znaku. Czy to wszystkie możliwości? Nie – można to przecież jeszcze połączyć i użyć raz z “@” a raz bez – ot tak, żeby było trudniej. Zatem do dzieła:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | using System; using System.Data; using System.Data.SqlClient; namespace SqlCmdParametersTest { class Program { static void Main(string[] args) { using (SqlConnection sqlConn = new SqlConnection(@"Data Source=localhost;Initial Catalog=SqlCmdParametersTest;Integrated Security=SSPI;Persist Security Info=true")) { sqlConn.Open(); using (SqlCommand sqlCmd = new SqlCommand()) { sqlCmd.CommandType = CommandType.StoredProcedure; sqlCmd.Connection = sqlConn; sqlCmd.CommandText = "[dbo].[spTest]"; //call with @ Console.WriteLine("With @"); sqlCmd.Parameters.Clear(); sqlCmd.Parameters.AddWithValue("@Param1", 1); sqlCmd.Parameters.AddWithValue("@Param2", 2); using (SqlDataReader reader = sqlCmd.ExecuteReader()) { ReadResult(reader); } //call without @ Console.WriteLine("Without @"); sqlCmd.Parameters.Clear(); sqlCmd.Parameters.AddWithValue("Param1", 1); sqlCmd.Parameters.AddWithValue("Param2", 2); using (SqlDataReader reader = sqlCmd.ExecuteReader()) { ReadResult(reader); } //call mixed Console.WriteLine("Mixed"); sqlCmd.Parameters.Clear(); sqlCmd.Parameters.AddWithValue("@Param1", 1); sqlCmd.Parameters.AddWithValue("Param2", 2); using (SqlDataReader reader = sqlCmd.ExecuteReader()) { ReadResult(reader); } } } Console.ReadLine(); } private static void ReadResult(SqlDataReader reader) { if (reader.Read()) { Console.WriteLine("Result:"); Console.WriteLine("{0} {1}", reader["Col1"], reader["Col2"]); } else { Console.WriteLine("Result is empty"); } } } } |
Wynik dziąłania aplikacji widać na rysunku poniżej:
Jak widać wynik jest zgodny z oczekiwaniami – wszystko działa poprawnie, nawet “mix”. Warto jeszcze sprawdzić co dociera do SQL Servera, bo może to on jest tą “sprytną stroną”… Po uruchomieniu SQL Profilera widzimy, że jednak krok ku wygodzie a przede wszystkim swobodzie jest po stronie .NET Framework.
Wniosek
Z SqlCommand.Parameters można korzystać swobodnie i bez martwienia się o “@” lub jej brak.
Prawda o SqlCommand.Parameters « Maciej Grabek…
Dziękujemy za publikację – Trackback z dotnetomaniak.pl…
A po jakimś czasie gdzieś pojawia się błąd który poprawia inna osoba i ta biedna osoba musi się zastanawiać czy nieużycie @ jest poprawne, czy nie jest poprawne i musi znów potwierdzić to testami.
Niby można pominąć ‘@’. Ale po co? Przyjęte jest, że zmienne bazodanowe zaczynają się od ‘@’, a SqlCommand.Parameters to nic innego jak ustawienie zmiennej bazodanowej.
Nie ukrywam, że sam na codzień praktykuję użycie “@” przy nazwach parametrów, jeżeli podaję je “jawnie”.
Sprawdzałem możliwości ze względu na to, że przy jednym z projektów było dużo przerzucania parametrów z “@” i bez, porównywania, łączenia słowników itp. W związku z tym chciałem się upewnić, czy warto mi “martwić” się sprawdzaniem “@” na początku, dodawaniem jej i tak po kilka razy…
Może komuś też to się przyda w podobnym zadaniu.
W projekcie parametry były pobierane dynamicznie, więc w kodzie nie było użycia “@Parameter” tylko były wrzucane wartości ze słowników. Teraz mam pewność, że działa i z “@” i bez