6.2 Formatting SQL
| (require toolbox/db/sql) | package: toolbox-db-lib |
If v is a string, it is used directly.
If v is a symbol, it is formatted as a SQL identifier using sql:id.
If v is an exact integer, it is converted using number->string.
If v is any other rational number, it is converted to a flonum using real->double-flonum, then converted to a string using number->string.
If v is sql-null, it is converted to the string "NULL".
> (~sql "SELECT " 'id " FROM " 'comment " WHERE " 'rating " > " 0.75) "SELECT \"id\" FROM \"comment\" WHERE \"rating\" > 0.75"
The ~sql function is especially useful when used @ syntax via the at-exp language.
Example:
@~sql{SELECT name FROM user WHERE id IN @sql:tuple*[user-ids]}
procedure
(sql:string name) → string?
name : (or/c symbol? string?)
> (sql:string "hello") "'hello'"
> (sql:string "it's") "'it''s'"
> (sql:seq 1 2 3) "1,2,3"
> (sql:seq* 1 2 '(3 4)) "1,2,3,4"
> (sql:tuple 1 2 3) "(1,2,3)"
procedure
(sql:tuple* v ... vs) → string?
v : pre-sql? vs : (listof pre-sql?)
> (sql:tuple* 1 2 '(3 4)) "(1,2,3,4)"
In a sense, query:bag is the inverse of query-list. However, because the query contains no ORDER BY clause, the order of the resulting rows cannot be guaranteed. If the order of vs is important, query:indexed-list should be used instead.
procedure
(query:indexed-list vs) → string?
vs : (listof pre-sql?)
> (query:indexed-list '(1 2 3)) "VALUES (0,1),(1,2),(2,3)"
> (query:indexed-list '()) "SELECT NULL,NULL WHERE 0"
> (query-list (~sql "WITH nums(i,n) AS (" (query:indexed-list (range 10)) ")\n" "SELECT n*n FROM nums ORDER BY i")) '(0 1 4 9 16 25 36 49 64 81)
procedure
(query:rows rows [#:columns num-columns]) → string?
rows : (listof (vectorof pre-sql?)) num-columns : (or/c exact-nonnegative-integer? #f) = #f
If num-columns is not #f, it supplies the number of columns the query should return. Otherwise, the number of columns is inferred from the length of the elements of rows. If num-columns is #f and no rows are provided, an exn:fail:contract exception is raised.
> (query:rows '(#(1 2) #(3 4) #(5 6))) "VALUES (1,2),(3,4),(5,6)"
> (query:rows '() #:columns 2) "SELECT NULL,NULL WHERE 0"
> (query:rows '()) query:rows: cannot infer number of columns;
no rows given and #:columns not specified
Pre-SQL values can be converted to SQL strings using ~sql.