Ejecución preparada
La API de ODBC define la ejecución preparada como una manera de reducir la sobrecarga de análisis y compilación asociada a la ejecución reiterativa de una instrucción Transact-SQL. La aplicación genera una cadena de caracteres que contiene una instrucción SQL y, a continuación, la ejecuta en dos fases. Llama una vez a SQLPrepare para que Database Engine (Motor de base de datos) analice y compile la instrucción en un plan de ejecución. A continuación, llama a SQLExecute para cada ejecución del plan de ejecución preparada. De esta forma, se guarda la sobrecarga de análisis y compilación en cada ejecución. Las aplicaciones suelen usar la ejecución preparada para ejecutar repetidamente una misma instrucción SQL parametrizada.
Para la mayoría de las bases de datos, la ejecución preparada es más rápida que la ejecución directa de instrucciones que se ejecutan más de tres o cuatro veces, principalmente porque la instrucción se compila solo una vez, mientras que las instrucciones ejecutadas directamente se compilan cada vez que se ejecutan. La ejecución preparada también puede proporcionar una reducción del tráfico de red porque el controlador puede enviar un identificador de plan de ejecución y los valores de los parámetros, en lugar de una instrucción SQL completa, al origen de datos cada vez que se ejecuta la instrucción.
En SQL Server 2000 y versiones posteriores se ha reducido la diferencia de rendimiento entre la ejecución directa y preparada a través de algoritmos mejorados para la detección y reutilización de planes de ejecución desde SQLExecDirect. Estos algoritmos permiten disfrutar en las instrucciones que se ejecutan directamente de algunas de las ventajas de rendimiento de la ejecución preparada. Para obtener más información, vea Ejecución directa.
SQL Server 2000 y versiones posteriores proporcionan también compatibilidad nativa con la ejecución preparada. Los planes de ejecución se crean en SQLPrepare y después se ejecutan al llamar a SQLExecute. Como en SQL Server 2000 y versiones posteriores no es necesario generar procedimientos almacenados temporales en SQLPrepare, no hay ninguna sobrecarga adicional en las tablas del sistema en tempdb.
Por motivos de rendimiento, la preparación de instrucciones se difiere hasta que se llama a SQLExecute o se realiza una operación de metapropiedad (como SQLDescribeCol o SQLDescribeParam en ODBC). Éste es el comportamiento predeterminado. Cualquier error que se produzca en la instrucción que se está preparando no se dará a conocer hasta que la instrucción se ejecute o hasta que se realice una operación de metapropiedad. Si desea desactivar este comportamiento predeterminado, establezca el atributo de instrucción específico del controlador ODBC de Native Client de SQL Server SQL_SOPT_SS_DEFER_PREPARE en SQL_DP_OFF.
En el caso de una preparación diferida, al llamar a SQLDescribeCol o SQLDescribeParam antes de llamar a SQLExecute, se genera un ciclo de ida y vuelta adicional en el servidor. En SQLDescribeCol, el controlador quita la cláusula WHERE de la consulta y la envía al servidor con SET FMTONLY ON para obtener la descripción de las columnas en el primer conjunto de resultados devueltos por la consulta. En SQLDescribeParam, el controlador llama al servidor para obtener una descripción de las expresiones o columnas a las que hacen referencia los marcadores de parámetros de la consulta. Este método tiene también algunas restricciones, como la imposibilidad de resolver parámetros en subconsultas.
El uso excesivo de SQLPrepare con el controlador ODBC de Native Client de SQL Server degrada el rendimiento, sobre todo en conexiones a versiones anteriores de SQL Server. La ejecución preparada no se debe utilizar para las instrucciones que se ejecutan una sola vez. La ejecución preparada es más lenta que la ejecución directa para una ejecución única de una instrucción porque requiere un ciclo de ida y vuelta de red adicional del cliente al servidor. En las versiones anteriores de SQL Server genera además un procedimiento almacenado temporal.
Las instrucciones preparadas no se pueden utilizar para crear objetos temporales en SQL Server 2000 o versiones posteriores, ni en las versiones anteriores de SQL Server, si la opción para generar procedimientos almacenados está activada. Con esta opción activada, la instrucción preparada se crea en un procedimiento almacenado temporal que se ejecuta cuando se llama a SQLExecute. Todos los objetos temporales creados durante la ejecución de un procedimiento almacenado se borran automáticamente cuando finaliza el procedimiento. Si la opción para generar procedimientos almacenados para la preparación está activada, no se creará ninguno de los resultados de los ejemplos siguientes en la tabla temporal #sometable:
SQLPrepare(hstmt,
"CREATE TABLE #sometable(cola int, colb char(8))",
SQL_NTS);
SQLExecute(hstmt);
o
SQLPrepare(hstmt,
"SELECT * FROM Authors INTO #sometable",
SQL_NTS);
SQLExecute(hstmt);
Algunas aplicaciones ODBC anteriores utilizaban SQLPrepare siempre que se usaba SQLBindParameter. SQLBindParameter no requiere el uso de SQLPrepare; se puede utilizar con SQLExecDirect. Por ejemplo, utilice SQLExecDirect con SQLBindParameter para recuperar el código de retorno o los parámetros de salida de un procedimiento almacenado que sólo se ejecuta una vez. No utilice SQLPrepare con SQLBindParameter a menos que se ejecute varias veces la misma instrucción.