select name from users where user_id = $current_user
If the variable is interpolated before the query is presented to Oracle,
the query could actually end up being different from what is written
in our code!
If the variable current_user
had the value "1 or 1=1", the above query
turns into:
select name from users where user_id = 1 or 1=1
users
table. Since a great deal of web programming is running database commands depending on user input,
this is a huge security problem.
To get around this, we use bind variables. Essentially, we put placeholders in our database commands and give Oracle the values for these placeholders. By leaving it up to Oracle to perform the variable interpolation, we eliminate the possibility of clauses being unknowingly inserted into our queries or DML statements(because Oracle will parse the query before interpolating the variables).
The API provides several ways to associate bind variables with a query, but the simplest is to simply put :varname in your SQL or DML statements wherever you have a TCL variable(with exceptions; see below). The above query would then become:
user_id
out of the environment and
take care of presenting it to Oracle in the correct manner. Inserts
and updates
work similarly:
db_null
null
(instead of the Oracle-specific idiom
of the empty string).
Use it instead of the empty string whenever you want to set a column
value explicitly to null
, e.g.:
set bar [db_null] set baz [db_null] db_dml foo_create "insert into foo(bar, baz) values(:bar, :baz)" # # sets the values for both the "bar" and "baz" columns to null
db_nextval sequence
db_foreach statement-name sql
code_block [ if_no_rows if_no_rows_block ]
sql
, executing code_block
once for each row with
variables set to column values (or a set or array populated if -column_array
or
column_set
is specified). If the query returns no rows, executes
if_no_rows_block
(if provided).
Example:
The code block may containdb_foreach select_foo "select foo, bar from greeble" { doc_body_append "<li>foo=$foo; bar=$bar\n" } if_no_rows { doc_body_append "<li>There are no greebles in the database.\n" }
break
statements (which terminate the
loop and flush the database handle) and continue
statements (which
continue to the next row of the loop).
db_1row statement-name sql
sql
, setting variables to column values.
Raises an error if the query does not return exactly 1 row.
Example:
db_1row select_foo "select foo, bar from greeble where greeble_id = $greeble_id" # Bombs if there's no such greeble! # Now $foo and $bar are set.
db_0or1row statement-name sql
sql
. If a row is returned, sets variables to column values
and returns 1. If no rows are returned, returns 0. If more than one row is returned, throws
an error.
Example:
db_string statement-name sql
sql
. If sql
doesn't return a row, returns default
(or throws an error if default
is unspecified).
db_list statement-name sql
sql
.
If sql
doesn't return any rows, returns an empty list.
db_list_of_lists statement-name sql
sql
.
If sql
doesn't return any rows, returns an empty list.
db_dml statement-name sql
sql
.
db_dml change_foo_name "update bar set foo_name = 'Joe Smith' where foo_id = :thisfooid
db_release_unused_handles
neal@arsdigita.com
Last modified: August 25 2000, 5:56 PM