sql >> Databasteknik >  >> RDS >> PostgreSQL

Gå och IN-klausul i Postgres

Förbygga SQL-frågan (förhindra SQL-injektion)

Om du genererar en SQL-sträng med en param-platshållare för vart och ett av värdena, är det lättare att bara generera den slutliga SQL-koden direkt.

Observera att eftersom värden är string s, det finns plats för SQL-injektionsattack, så vi testar först om alla string värden är verkligen siffror, och vi fortsätter bara om så är fallet:

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(")")

Utför det:

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

Använda ANY

Du kan också använda Postgresqls ANY , vars syntax är följande:

expression operator ANY (array expression)

Med det kan vår fråga se ut så här:

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

I det här fallet kan du deklarera arrayens textform som en parameter:

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

Som helt enkelt kan byggas så här:

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

Observera att ingen kontroll krävs i det här fallet eftersom array-uttrycket inte tillåter SQL-injektion (utan snarare kommer att resultera i ett frågekörningsfel).

Så hela koden:

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. Sammanfoga JSONB-värden i PostgreSQL?

  2. SQL Server-filnamn kontra versioner

  3. Hur man formaterar ett datum i T-SQL

  4. MySQL-jämförelse med nullvärde