db_exec (public)
db_exec [ -subst subst ] type db statement_name pre_sql [ ulevel ] \ [ args... ]
Defined in packages/acs-tcl/tcl/01-database-procs.tcl
A helper procedure to execute a SQL statement, potentially binding depending on the value of the $bind variable in the calling environment (if set).
- Switches:
- -subst (optional, defaults to
"all"
)- Parameters:
- type (required)
- db (required)
- statement_name (required)
- pre_sql (required)
- ulevel (optional, defaults to
"2"
)- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- db__0or1row, db__1row, xowiki_test_cases
Source code: set start_time [expr {[clock clicks -microseconds]/1000.0}] set driverkey [db_driverkey -handle_p 1 $db] set sql [db_qd_replace_sql -ulevel [expr {$ulevel +1 }] -subst $subst $statement_name $pre_sql] set errno [catch { upvar bind bind if { [info exists bind] && [llength $bind] != 0 } { if { [llength $bind] == 1 } { # $bind is an ns_set id: switch -- $driverkey { oracle { return [ns_ora $type $db -bind $bind $sql {*}$args] } postgresql { return [ns_pg_bind $type $db -bind $bind $sql] } nsodbc { return [ns_odbc_bind $type $db -bind $bind $sql] } default { error "Unknown database driver. Bind variables not supported for this database." } } } else { # $bind is a Tcl list, convert it to an ns_set: set bind_vars [ns_set create] foreach { name value } $bind { ns_set put $bind_vars $name $value } } switch -- $driverkey { oracle { # TODO: Using $args outside the list is # potentially bad here, depending on what is in # args and if the items contain any embedded # whitespace. Or maybe it works fine. But it's # hard to know. Document or fix. # --atp@piskorski.com, 2003/04/09 15:33 EDT return [ns_ora $type $db -bind $bind_vars $sql {*}$args] } postgresql { return [ns_pg_bind $type $db -bind $bind_vars $sql] } nsodbc { return [ns_odbc_bind $type $db -bind $bind_vars $sql] } default { error "Unknown database driver. Bind variables not supported for this database." } } } else { # Bind variables, if any, are defined solely as individual # Tcl variables: switch -- $driverkey { oracle { return [uplevel $ulevel [list ns_ora $type $db $sql] $args] } postgresql { return [uplevel $ulevel [list ns_pg_bind $type $db $sql]] } nsodbc { return [uplevel $ulevel [list ns_odbc_bind $type $db $sql]] } default { # Using plain ns_db like this will work ONLY if # the query is NOT using bind variables: # --atp@piskorski.com, 2001/09/03 08:41 EDT return [uplevel $ulevel [list ns_db $type $db $sql] $args] } } } } error] # # If db_exec took more than a threshold, yack about it. We have to # be careful there, since this might be called during bootstrap, # where "parameter::get_from_package_key" is not yet defined. We # cannot use "parameter::get_from_package_key" directly, since # this needs an SQL query, leading to an infinite recursion. So, # we use a per-thread variable, which is set at startup and then # updated, whenever the parameter changes. # set complain_time [expr {[info exists ::acs::DbLogMinDuration] ? $::acs::DbLogMinDuration : 2000 }] if { [clock clicks -milliseconds] - $start_time > $complain_time} { set duration [format %.2f [expr {[clock clicks -milliseconds] - $start_time}]] ns_log Warning "db_exec: longdb $duration ms $db $type $statement_name" } else { #set duration [format %.2f [expr {[clock clicks -milliseconds] - $start_time}]] #ns_log Debug "db_exec: timing $duration seconds $db $type $statement_name" } ds_collect_db_call $db $type $statement_name $sql $start_time $errno $error if { $errno == 2 } { return $error } return -code $errno -errorinfo $::errorInfo -errorcode $::errorCode $errorXQL Not present: Generic, PostgreSQL, Oracle