spróbuj wstawić wiersz do bazy danych serwera sql za pomocą C # ado, net

Nov 24 2020

Próbuję wstawić wiersz do bazy danych SQL Server za pomocą Ado.Net w aplikacji konsolowej. Czytam dane wejściowe z klawiatury ....

oto mój kod:

private void InsertStudents(string con)
{      
   SqlConnection Connection = new SqlConnection(con);
   SqlDataAdapter adapter = new SqlDataAdapter();

   int id               = Convert.ToInt32(Console.ReadLine());
   string     firstName = Console.ReadLine();
   string      lastName = Console.ReadLine();
   DateTime dateOfBirth = Convert.ToDateTime(Console.ReadLine());
   double   tuitionFees = Convert.ToDouble(Console.ReadLine());

   string sql = "$insert into product (ID,FirstName,LastName,DateOfBirth,TuitionFees) values {id}, {firstName}, {lastName}, {dateOfBirth}, {tuitionFees})";
   try
   {
        Connection.Open();
        adapter.InsertCommand = new SqlCommand(sql, Connection);
        adapter.InsertCommand.ExecuteNonQuery();
        Console.WriteLine(" 1 Row inserted!");
   }
   catch (Exception ex)
   {
        Console.WriteLine(ex.ToString());
   }
}

moim problemem jest to, że kompilator odczytuje mój interpolowany ciąg jako ciąg, ale nie rozpoznaje kolumn jako zmiennych ... czyta cały wiersz jako pojedynczy ciąg. Jaki jest problem?

Odpowiedzi

3 MarcGravell Nov 24 2020 at 10:41

To jest bardzo ważne: nie używaj interpolowanych ciągów w SQL; jest zły pod każdym względem :

  • bezpieczeństwo: iniekcja SQL
  • wydajność: ponowne wykorzystanie planu zapytań
  • niezawodność: kruchość z zastrzeżonymi symbolami, takimi jak '
  • poprawność: kwestie i18n / l10n (czyli formatowanie) - szczególnie istotne dla DateTimewartości (data urodzenia; czy „07/11/2020” to 7 listopada? czy 11 lipca?) - ale również wysokość czesnego (w „123 456”, czy przecinek jest separatorem dziesiętnym (Francja i inni)? Czy separatorem grupy?)

Prawidłowe podejście to parametry . Zawsze.

Tak więc SQL jak:

insert into product (ID,FirstName,LastName,DateOfBirth,TuitionFees)
values (@id, @firstName, @lastName, @dateOfBirth, @tuitionFees)

I to zrobić, albo dowiedzieć się o parametrach ADO.NET, czyli użyć narzędzia jak Dapper który upraszcza to:

int id = ...
string firstName = ...
string lastName =  ...
DateTime dateOfBirth = ...
double   tuitionFees = ...

using var conn = new SqlConnection(con); // Dapper will deal with the open/close
conn.Execute(@"
insert into product (ID,FirstName,LastName,DateOfBirth,TuitionFees)
values (@id, @firstName, @lastName, @dateOfBirth, @tuitionFees)",
    new { id, firstName, lastName, dateOfBirth, tuitionFees });

Ostatnia uwaga: nie używaj doubledo waluty; używać decimal. doublenie nadaje się do kwot w walutach.

jason.kaisersmith Nov 24 2020 at 09:49

Umieściłeś znak dolara wewnątrz łańcucha, zamiast przed nim. Powinno być:

string sql = $"insert into product (ID,FirstName,LastName,DateOfBirth,TuitionFees) values {id}, {firstName}, {lastName}, {dateOfBirth}, {tuitionFees})";