Przygotowane instrukcje
Wykonuj zapytania parametryzowane
Przygotowane instrukcje to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.
Czym jest prepared statement
Prepared statement wysyła tekst SQL do bazy danych raz, aby został przeanalizowany i zoptymalizowany, a następnie wykonuje go wielokrotnie z różnymi parametrami. Przy powtarzających się zapytaniach jest szybszy i lepiej chroni przed wstrzykiwaniem SQL.
Symbole zastępcze parametrów
Nigdy nie należy tworzyć SQL przez konkatenację danych wejściowych użytkownika. Należy używać symboli zastępczych, aby sterownik wysyłał wartości oddzielnie. PostgreSQL używa $1, $2, a MySQL i SQLite używają ?.
SELECT * FROM users WHERE age > $1 AND city = $2Dlaczego zapobiega to wstrzykiwaniu
Ponieważ parametry są przesyłane niezależnie od tekstu SQL, baza danych traktuje je wyłącznie jako dane, nigdy jako kod. Złośliwa wartość taka jak " OR 1=1 staje się dosłownym ciągiem znaków, a nie wykonywalnym SQL.
db.Prepare
Prepare zwraca obiekt *sql.Stmt powiązany z pulą. Następnie na instrukcji wywołuje się Exec lub Query, przekazując argumenty.
stmt, err := db.Prepare("INSERT INTO users(name, age) VALUES($1, $2)")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()Wykonywanie instrukcji
Należy wywołać stmt.Exec, przekazując argumenty odpowiadające poszczególnym symbolom zastępczym. W przypadku wstawiania i aktualizowania danych Exec zwraca obiekt sql.Result zawierający liczbę zmodyfikowanych wierszy oraz identyfikator ostatnio wstawionego rekordu.
res, err := stmt.Exec("Ada", 36)
if err != nil {
log.Fatal(err)
}
n, _ := res.RowsAffected()
fmt.Println("inserted", n)Ponowne użycie w pętli
Korzyść wynika z ponownego użycia: instrukcję należy przygotować raz, a następnie wykonywać ją wielokrotnie wewnątrz pętli. Baza danych ponownie wykorzystuje przeanalizowany plan przy każdym wywołaniu.
for _, u := range users {
if _, err := stmt.Exec(u.Name, u.Age); err != nil {
log.Fatal(err)
}
}Niejawne przygotowanie
Bezpośrednie przekazanie argumentów do db.Query lub db.Exec również bezpiecznie używa symboli zastępczych; sterownik może przygotować instrukcję wewnętrznie. Jawne użycie Prepare ma znaczenie głównie przy wielokrotnym wykonywaniu instrukcji.
Symulacja wiązania parametrów możliwa do uruchomienia
Prawdziwe przygotowane instrukcje wymagają bazy danych. Ten przykład możliwy do uruchomienia symuluje bezpieczne wiązanie parametrów, aby pokazać, jak wartości pozostają oddzielone od tekstu zapytania.
package main
import "fmt"
func execPrepared(query string, args ...interface{}) string {
return fmt.Sprintf("EXEC %q with args %v", query, args)
}
func main() {
q := "INSERT INTO users(name, age) VALUES($1, $2)"
people := [][2]interface{}{{"Ada", 36}, {"Lin", 41}}
for _, p := range people {
fmt.Println(execPrepared(q, p[0], p[1]))
}
}Warianty kontekstowe
Użyj PrepareContext i stmt.ExecContext, aby przygotowane wywołania respektowały limity czasu i anulowanie, tak jak pozostałe elementy database/sql.
Zawsze zamykaj Stmt
Obiekt *sql.Stmt zajmuje zasoby bazy danych. Gdy skończysz, odrocz wywołanie stmt.Close() za pomocą defer. Wycieki instrukcji mogą wyczerpać limity przygotowanych instrukcji po stronie serwera.
Instrukcje i pooling
Instrukcja przygotowana na obiekcie *sql.DB działa na różnych połączeniach z puli; biblioteka przygotowuje ją ponownie na tym połączeniu, na którym zostanie wykonana. Zwykle nie trzeba zarządzać tym samodzielnie.
Szybkie sprawdzenie
Sprawdź swoją wiedzę na temat przygotowanych instrukcji.
Podsumowanie
Użytkownik poznał przygotowane instrukcje:
- Prepare analizuje instrukcję raz, a następnie można wykonywać ją wielokrotnie
- Symbole zastępcze ($1 lub ?) przechowują wartości jako dane, zapobiegając wstrzyknięciom
- stmt.Exec zwraca liczbę zmodyfikowanych wierszy; należy odroczyć wywołanie stmt.Close()
- Należy używać ponownie instrukcji w pętlach, a wariantów Context w przypadku terminów
Często zadawane pytania
Czy lekcja „Przygotowane instrukcje” jest bezpłatna?
Tak — pełny tekst „Przygotowane instrukcje” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Przygotowane instrukcje”?
Wykonuj zapytania parametryzowane Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Go Academy?
Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Przygotowane instrukcje”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?
Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Otwieranie połączenia
- Wykonywanie zapytań dotyczących wierszy
- Przygotowane instrukcje
- Transakcje