Working With TSQLQuery/es

From Lazarus wiki
Jump to navigationJump to search

English (en) español (es) français (fr) 日本語 (ja) polski (pl) 中文(中国大陆)‎ (zh_CN)

   Para una referencia general de cómo trabajar con Bases de Datos ver Bases de Datos en Lazarus

Trabajando con TSQLQuery

   El conjunto de datos (DataSet) que devuelve TSQLQuery se puede ver con una instancia de TDBGrid, pero no es muy recomendable para editar los campos de los registros individuales. Para realizar esto en conveniente poner varios componentes ligados a datos para registros individuales, cómo TDBEdit en el formulario, y poner su propiedad DataSource con el valor de nombre de la fuente de datos utilizada. En la propiedad DataField seleccionaremos el nombre del campo (v.gr. 'IDENTIDAD') o una expresión que resulte en una cadena aceptable.

   Si añadimos un componente de navegación TDBNavigator Lazarus TDBNavigator.png resultará muy fácil moverse por los registros y seleccionarlos para editarlos. Cuándo un registro es seleccionado mediante un TDBNavigator o moviendo el cursor en el DBGrid los datos correspondientes del registro se mostrarán en el TDBEdity si se pulsa el botón de Editar Lazarus TDBNavigator.Editar.png, su contenido puede ser modificado. Con el botón Post Lazarus TDBNavigator.Guardar.png podemos confirmar la edición o bien desechar los cambios con Cancelar Lazarus TDBNavigator.Cancelar.png.

   En general el proceso es el siguiente:

  1. Sitúa un componente TSQLQuery en el formulario o móulo de datos, da los valores adecuados a las propiedadesDatabase, Transaction y SQL.
  2. Sitúa un componente TDatasource, haz que su propiedad Dataset apunte a la instancia de TSQLQuery.
  3. Sitúa un componente TDBGrid en el formulario, selecciona en su propiedad Datasource el nombre dado al componente TDatasource anterior.
  4. Opcionalmente sitúa un componente TDBNavigator y da valor a su propiedad Datasource para usar el TDatasource.

   Tras esto poner la propiedad Active a verdadero (True), y podremos ver los datos suministrados por la consulta.

   Los componentes TSQLConnection y TSQLTransaction, que también hemos puesto en el formulario, tienen su propiedad Active a verdadera.

Actualización de datos

   Si es necesario poder Borrar o modificar registros, la Base de datos tiene que

  1. Tener una columna con la Clave Primaria.
  2. Tener un conjunto de campos que individualicen cada registro, que normalmente serán parte del índice único. Este índice no es imprescindible, pero contribuirá a que las consultas sean más rápidas.

   Si no existen ni el campo primario ni esos campos que individualizan un registro será necesario añadir un registro de clave primaria. Esto se realiza preferiblemente al diseñar la estructura de la tabla en el momento de crearla, pero podemos añadirla posteriormente.

   El siguiente código en un cliente MySQL, por ejemplo, añadirá un índice único para su tabla. <delphi> alter table ejemplo1

 add column autoidentificador int 
 primary key auto_increment;</delphi>

   La adición del campo no estropeará nada y permitirá a tus aplicaciones para actualizarlo.

Cambios diferidos (cached)

   El componente TSQLQuery guarda los cambios en un espacio de memoria intermedia. Es decir, los cambios no son enviados inmediatamente a la Base de datos, si no que se mantienen en memoria hasta que llamamos al método ApplyUpdates. En ese momento los cambios se transforman en sentencias DML de SQL, y son aplicadas a la Base de datos. Si no se utiliza el método ApplyUpdates, la Base de datos no será actualizada con los cambios locales realizados.

Campos de Clave primaria

   Cuándo se actualizan registros, TSQLQuery necesita conocer que campos constituyen la clave primaria que se utiliza para modificar un registro y cuáles son los campos que se van a modificar: basándose en esta información construirá la sentencia SQL adecuada UPDATE, INSERT o DELETE.

   La creación de la sentencia SQL se controla con las propiedades UsePrimaryKeyAsKey y ProviderFlags.

   La propiedad Providerflags está compuesta de 3 indicadores:

   pfInkey
El campo forma parte de la clave primaria
   pfInWhere
El campo puede utilizarse en la cláusula WHERE de una sentencia SQL.
   pfInUpdate
LAs modificaciones o inserciones deben incluir este campo.

   Por defecto, ProviderFlags tiene puesto el indicador de pfInUpdate.

   Si la tabla dispone de un clave primaria (cómo se describe más arriba) es necesario poner la propiedad UsePrimaryKeyAsKey a verdadera True y lo tendremos todo hecho. De esta forma, se establecerá el indicador pfInKey para los campos de la clave primaria.

   Si la tabla no dispone de un clave primaria, pero existen campos que permiten individualizar los registros se deberá incluir el indicador pfInKey en la propiedad ProviderFlags de todos los registros que identifican el registro cómo único.

   La propiedad UpdateMode determina los registros que pueden ser utilizados en la cláusula WHERE:

   upWhereKeyOnly
En el momento de construir una cláusula WHERE TSQLQuery lista todos los campos que tienen el indicador pfInKey en su propiedad ProviderFlags y utiliza los valores para crear la cláusula WHERE que determina el registro cómo único para modificar sus valores -- normalmente esto sólo es necesario para las sentencias UPDATE y DELETE.
   upWhereChanged
Además de los campos con el indicador pfInKey en su propiedad ProviderFlags, los campos con el indicador pfInWhere y que han sido modificados, se incluyen en la cláusula WHERE.
   upWhereAll
Los campos con el indicador pfInWhere en su propiedad ProviderFlags serán también incluidos para crear las cláusula WHERE.

Controlando los cambios

   Es posible especificar que campos pueden ser modificados: se mencionó antes: Únicamente los campos que tienen el indicador pfInUpdate en su propiedad ProviderOptions se pueden incluir en sentencias SQL UPDATE o INSERT. Por defecto el indicador pfInUpdate está presente en la propiedad ProviderOptions.

Customizing the SQL in TSQLQuery

   Normally TSQLQuery will use generic SQL statements based on properties as discussed above. However, the generic SQL created by sqldb may not be correct for your situation. TSQLQuery allows you to customize SQL statements used for the various actions, to work best in your situation with your database. For this purpose you use the properties SQL, InsertSQL, UpdateSQL and DeleteSQL.

   All these properties are of type TStringList, a list of strings, that accepts multiple lines of SQL. All four come with a property editor in the IDE. In the IDE, select the property and open de editor by clicking the ellipsis button. In code, use for example InsertSQL.Text or InsertSQL.Add() to set or add lines of SQL statements. One statement may span several lines and ends with a semicolon.

   Also, all four properties accept parameters explained further below.

TSQLQuery.SQL: Basic SQL Customization

   The SQL property is normally used to fetch the data from the database. The generic SQL for this property is SELECT * FROM fpdev where fpdev is the table as set in the database.

   The dataset returned by the generic SQL statement will be kind of rough. If you show the result in a TDBGrid, the order of the records may seem random, the order of the columns may not be waht you want and the field names may be technically correct but not user friendly. Using customized SQL you can improve this.    SELECT id AS 'ID', UserName AS 'User', InstEmail AS 'e-mail' FROM fpdev ORDER BY id;    The table in the database has the columns id, UserName and InstEmail. The dataset that results from the above query uses the field names as given in the query(ID, User and e-mail), the column order as given in the query and the records are sorted by their id.

TSQLQuery.InsertSQL, TSQLQuery.UpdateSQL and TSQLQuery.DeleteSQL: Basic Use of Parameters

   The statements in InsertSQL, UpdateSQL and DeleteSQL accept parameters. Field names used in these statements must be exactly the same as the field names used in the dataset. The field names in the dataset may be different from the column names in the table, depending on the used select statement (see above). Field values must be written as the field name preceded by a colon. For example:    INSERT INTO fpdev(id, UserName, InstEmail) VALUES(:id,:UserName,:InstEmail);    This statement will insert the values of id, UserName and InstEmail from the current record of the dataset into the respective fields of table fpdev.

   The previously shown INSERT statement is a generic INSERT statement and would be of limited use in TSQLQuery as it will be the same as the SQL generated with slqdb itself. The given statement may result in errors when the id field is an auto-increment field in a unique key. Different databases solve this problem in different ways. For example, the following works for MySQL.    INSERT INTO fpdev(id, UserName, InstEmail) VALUES(0,:UserName,:InstEmail)    ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID();    The above statement tries to insert a new record using 0 (zero) for the id. If zero is already used as a key, then a duplicate is detected and the id is updated to use the last inserted id. Well, actually an id one increment higher than the last one used.

   For an INSERT statement you may want to use the current field values of the selected record. For UPDATE statements, you will want to use the field values as they were before editing in the WHERE clause. This is also possible. The field values before editing must be written as the field name precede by ':old_'. For example, the following works for MYSQL:    UPDATE fpdev SET UserName=:UserName, InstEmail=:InstEmail WHERE UserName=:Old_UserName;    The above statement updates the UserName and InstEmail fields of all records where UserName equals the old UserName value.

   We leave it as an exercise to the reader to use the current field values and the old field values in DELETE statements.

Parameters in TSQLQuery.SQL

   In most situations, the SQL property of TSQLQuery will contain the select statement which again in most situations doesn't need parameters. However, even the SQL property can contain parameters. Where the InsertSQL, UpdateSQL and DeleteSQL properties can use predefined parameters for current and old field values the SQL property does not. You can create your own parameters in the Params property.

   The use of parameters may help performance of the database. Most databases support prepared statements, which means that the statement is prepared and cached in the database. A prepared statement can be used more than once and doesn't require parsing and planning every time it is used, only the parameters are changed each time it is used. In situations where the same statement is used a large number of times -with only an exchange of parameters - prepared statements can help performance considerably.

   Although SqlDBHowto/nl contains a brief discussion in Dutch on this subject. I don't understand the technology and properties that can be set enough to discuss it in more detail.