2009-01-05 9 views
6

qué método prefiere para crear consultas SQL dinámicas? formateo o transmisión? ¿Es solo una preferencia o hay alguna razón por la cual uno es mejor que otro? O cualquier biblioteca especial que use para ello.crear consultas sql en C++/java?

EDITAR: Responda en caso de C++.

Respuesta

4

En Java debe usar un PreparedStatement.

PreparedStatement statement = connection.prepareStatement("SELECT * FROM Table WHERE ID = ?"); 
statement.setInt(1, 17); 
ResultSet resultSet = statement.executeQuery(); 
+0

gracias, ¿cómo prevenir en C++? – yesraaj

+0

No tengo idea, C++ no es mi taza de té. :) – Bombe

6

Use siempre "preparar" habrá un equivalente a prepareStatement pero el nombre de la función exacta dependerá de su base de datos y combinación conductor.

Las ventajas de una declaración preparada a través de una ejecución (cadena) son muchas: - se analiza

La declaración y un plan de acceso determind sólo una vez cuando se ejecuta el "preparar" comunicado. Dependiendo de cuántas veces ejecute la instrucción, esto puede dar como resultado un rendimiento mucho mejor.

No necesita preocuparse por los caracteres especiales en los datos de cadena cuando pase por setString(). En una ejecución (String), cualquier comilla simple o punto y coma en los datos dará como resultado un error de análisis.

Peor es así como funcionan los ataques de "inyección sql". Si una cadena algo así como "x" de cust_table ; delete from cust _ table ; select "se ingresa como datos, podría resultar en la declaración de eliminación analizada y ejecutada.

El manejo de números es mucho más eficiente. Una llamada setInt toma un valor entero como es para la cadena SQL equitativa que debe convertir a caracteres, entonces el DBMS tiene que convertirlo de nuevo a un número entero.

Legibilidad. Codifica una única sentencia de SQL con unos pocos signos de interrogación donde van las variables que es relativamente fácil de leer, en lugar de analizar mentalmente y analizar una serie de concatenaciones de cadena, habrá ruido adicional para las comillas escapadas, etc.

Sin embargo, hay par de casos donde execute (String) es realmente mejor.

Donde sus llaves se distribuyen de forma muy desigual. P.EJ. Si el 95% de sus clientes vive en los EE. UU. Y desea incluir el 4% que vive en Canadá, ¿en qué país es? normalmente daría como resultado un escaneo de espacio de tabla, mientras que con "donde país = 'CA'" tiene alguna posibilidad de usar un índice.

El otro caso es donde el usuario puede ingresar u omitir varios criterios de búsqueda. Es mucho mejor construir una cadena SQL para los criterios que se le dan que construir una consulta compleja que haga frente a todas las posibles permutaciones de los criterios de entrada.

1

Al usar comandos preparados no son posibles, encuentro utilizando flujos de C++ es la mejor manera de escribir la consulta:

std::ostringstream sql; 
sql << "exec loadStuff(" << param1 << ", " << param2 << ")"; 

No tener que preocuparse acerca de los tipos de los parámetros y la longitud de la ¡la cuerda es genial!

+0

Dudo en votar, pero me preocupa la amenaza de los ataques de inyección SQL en esa técnica. :( –

+1

Es bastante justo, pero cuando uso una biblioteca que no tiene declaraciones preparadas, en una aplicación interna que trata principalmente con números, he encontrado que este patrón es útil y eficiente para llamar a procedimientos almacenados. Una aplicación web orientada hacia el mundo sería otra cosa. –

+0

Disculpe, small_duck. No capté el bit "Cuando uso las declaraciones preparadas no son posibles." Iba a revocar mi voto a favor, pero afirma que mi voto negativo es demasiado viejo para revertir. Si edita su respuesta, puedo revocarla. Quizás podría marcar el bit de "no son posibles" para ayudar a las personas que tuvieron el mismo defecto que yo :) –