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
(defaults to "all") (optional)
Parameters:
type
db
statement_name
pre_sql
ulevel (defaults to "2")

Partial Call Graph (max 5 caller/called nodes):
%3 test_db__0or1row db__0or1row (test acs-tcl) db_exec db_exec test_db__0or1row->db_exec test_db__1row db__1row (test acs-tcl) test_db__1row->db_exec test_xowiki_test_cases xowiki_test_cases (test xowiki) test_xowiki_test_cases->db_exec db_driverkey db_driverkey (public) db_exec->db_driverkey db_qd_replace_sql db_qd_replace_sql (public) db_exec->db_qd_replace_sql ds_collect_db_call ds_collect_db_call (public) db_exec->ds_collect_db_call db_0or1row db_0or1row (public) db_0or1row->db_exec db_dml db_dml (public) db_dml->db_exec db_exec_plsql db_exec_plsql (public) db_exec_plsql->db_exec db_list db_list (public) db_list->db_exec db_list_of_lists db_list_of_lists (public) db_list_of_lists->db_exec

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 $error
XQL Not present:
Generic, PostgreSQL, Oracle
[ hide source ] | [ make this the default ]
Show another procedure: