sql >> Databáze >  >> RDS >> PostgreSQL

Klauzule Go a IN v Postgresu

Předběžné sestavení dotazu SQL (zabránění vložení SQL)

Pokud generujete řetězec SQL se zástupným symbolem param pro každou z hodnot, je jednodušší okamžitě vygenerovat konečné SQL.

Všimněte si, že protože hodnoty jsou string s, je zde místo pro útok SQL injection, takže nejprve otestujeme, zda jsou všechny string hodnoty jsou skutečně čísla a pokračujeme, pouze pokud ano:

tags := []string{"1", "2", "3"}
buf := bytes.NewBufferString("SELECT COUNT(id) FROM tags WHERE id IN(")
for i, v := range tags {
    if i > 0 {
        buf.WriteString(",")
    }
    if _, err := strconv.Atoi(v); err != nil {
        panic("Not number!")
    }
    buf.WriteString(v)
}
buf.WriteString(")")

Provádí se:

num := 0
if err := Db.QueryRow(buf.String()).Scan(&num); err != nil {
    log.Println(err)
}

Pomocí ANY

Můžete také použít ANY Postgresql , jehož syntaxe je následující:

expression operator ANY (array expression)

Pomocí toho může náš dotaz vypadat takto:

SELECT COUNT(id) FROM tags WHERE id = ANY('{1,2,3}'::int[])

V tomto případě můžete deklarovat textovou formu pole jako parametr:

SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])

Což lze jednoduše postavit takto:

tags := []string{"1", "2", "3"}
param := "{" + strings.Join(tags, ",") + "}"

Všimněte si, že v tomto případě není vyžadována žádná kontrola, protože výraz pole neumožní vložení SQL (ale spíše povede k chybě při provádění dotazu).

Takže celý kód:

tags := []string{"1", "2", "3"}

q := "SELECT COUNT(id) FROM tags WHERE id = ANY($1::int[])"
param := "{" + strings.Join(tags, ",") + "}"

num := 0
if err := Db.QueryRow(q, param).Scan(&num); err != nil {
    log.Println(err)
}


  1. count(*) a count(název_sloupce), jaký je rozdíl?

  2. Vytvoření clusteru Docker Swarm Cluster ve službě Azure Container Service

  3. Jak extrahovat podřetězec z řetězce v T-SQL

  4. Jak funguje funkce OCTET_LENGTH() v MySQL