domingo, diciembre 07, 2008

Firebird 2.1 UPDATE OR INSERT

Another great feature that I like in Firebird 2.1 is the UPDATE OR INSERT statement. It's a really time saver and it makes the SQL cleaner.

For example suppose I have a products table like the one I use in my last post and an inventory table to store the product stock. Before Firebird 2.1 if I want to set the stock for a product I needed to check if a record for that product_id already exists; if the product_id already exists then I write an update. If not then I write an insert statement. So I ended up with something like this:


IF EXISTS(SELECT * FROM inventory WHERE product_id = :product_id ) THEN
UPDATE
inventory
SET
stock = :stock
WHERE
product_id = :product_id;
ELSE
INSERT INTO inventory
(product_id, stock)
VALUES
(:product_id, :stock);

In this example I only update one field but when I have to update a big table I ended up with a big chunk of code and thinking: "there should be another (better) way to do this".

Fortunately now with Firebird 2.1 there is a better way to do it, I only need to use the UPDATE OR INSERT statement and the engine will take care of checking if the record already exists, based on the primary key value. If the table does not have a primary key defined then I should use the MATCHING keyword with the columns I want to match. So in this example the sql can look like this:

--product_id is the primary key

UPDATE OR INSERT INTO inventory
(product_id, stock)
VALUES
(:product_id, :stock);

or like this

--product_id is not defined as the primary key

UPDATE OR INSERT INTO inventory
(product_id, stock)
VALUES
(:product_id, :stock)
MATCHING
(product_id);


This code looks much cleaner and does not need any comments to explain what is going on.

I really like this new feature.

martes, septiembre 02, 2008

Firebird 2.1 Domains in PSQL

I Often use this domains in my Firebird databases

CREATE DOMAIN STRING AS VARCHAR(50) CHARACTER SET ISO8859_1 COLLATE ES_ES_CI_AI; /* for Spanish text */
CREATE DOMAIN MONEY AS DECIMAL(15, 2);
CREATE DOMAIN BOOL AS SMALLINT CHECK VALUE = 0 OR VALUE = 1;

So I can use them in my tables definitions like this:

CREATE TABLE PRODUCTS(
ID INTEGER,
DESCRIPTION STRING,
PRICE MONEY,
ACTIVE BOOL
)
ALTER TABLE PRODUCTS ADD CONSTRAINT PK_PRODUCTOS PRIMARY KEY (ID);

Before Firebird 2.1 when I wanted to create a stored procedure I had to write the data type of the domain instead of the domain name, like in the table definition, so I had to check the domain definition and write the data type on the procedure definition, although IBExpert help with that, my Stored Proc definition end it up not using the domains like this:

CREATE PROCEDURE INSERT_PRODUCT(
DESCRIPTION VARCHAR(50),
PRICE DECIMAL(15, 2),
ACTIVE SMALLINT
)
BEGIN
...
END

Now with version 2.1 I can use domain in PSQL. I just need to type the domain name if i want to inheriting the check clause and the default value, or I can use the TYPE OF keyword if I just want the data type so I can define something like this:

CREATE PROCEDURE INSERT_PRODUCT(
DESCRIPTION STRING,
PRICE TYPE OF MONEY,
ACTIVE BOOL
)
BEGIN
...
END

This way it seems that there is more consistency on my data types.

jueves, agosto 28, 2008

Firebird 2.1 Autentificar con Windows

La mayoría de las aplicaciones que desarrollo que utilizan Firebird son de tipo Cliente/Servidor lo cual hace que el deba de guardar al usuario y contraseña en la cadena de conexión almacenada en la maquina cliente.

Ahora con Firebird 2.1 puedo usar los usuarios de windows como usuarios de la base de datos, de este modo no necesito almacenar el usuario y contraseña en la maquina cliente.

Utilizando Delphi o C++ Builder con DbExpress para conectarme a la base de datos puedo agregar el archivo dbConnections.ini y dejar en blanco los valores de user_name y password. El archivo quedaría similar a esto:

[MyFirebirdDatabase]
DriverName=INTERBASE
GETDRIVERFUNC=getSQLDriverINTERBASE
DATABASE=Server:Database
PASSWORD=
USER_NAME=
SQLDIALECT=3

Si uso .Net y el Firebird .Net Data Provider la cadena de conexión puede quedar algo asi:
Database=MyDatabase.fdb;DataSource=MyServer;Dialect=3;

Si el usuario es administrador entonces ingresará al servidor de firebird como el usuario SYSADMIN si no usara el usuario d windows actual.

Ahora solo debo de agregar los usuarios de windows a los usuarios de la base de datos y windows se encargará de autentificar.

Firebird Windows Authentication

Most of the applications I write that use Firebird are Client/Server applications storing the user name and password to access the database in the connection string in the client machine.

Now with Firebird 2.1 you can use windows authentication so the client will use the windows user to log on to the server. This way I don't need to store the user name and password on the connection string in the client.

MS SQL Server has this feature for long time now. but it's great to have it on Firebird too.

Using Delphi or C++ Builder with DbExpress to accesss firebird in the dbconnections.ini file I just leave blank the user_name and password values, so I could have something like this:

[MyFirebirdDatabase]
DriverName=INTERBASE
GETDRIVERFUNC=getSQLDriverINTERBASE
DATABASE=Server:Database
PASSWORD=
USER_NAME=
SQLDIALECT=3

Using the Firebird .Net Data Provider the connection string will end up like this:
Database=MyDatabase.fdb;DataSource=MyServer;Dialect=3;

If the windows user is an administrator it will log in to the server as the SYSADMIN user. if the user is not an admin then the user will log in as the windows user.

Now I only have to add the windows users as database users and Windows will take care of authenticate them.

miércoles, julio 02, 2008

Firebird 2.1

Estoy empezando a usar Firebird 2.1 y estoy contento con las nuevas características. Aun no he tenido de oportunidad de usar todo lo nuevo, aquí esta una lista de lo nuevo que he estado usando, espero escribir de cada una de ella con mas detalle en los próximos posts
  • Seguridad usando usuarios de Windows
  • Parámetros Opcionales en procedimientos almacenados
  • Dominios en los parámetros de los procedimientos
  • Natural Join
  • La función List
  • Sentencia Update or Insert
Hay mas características en la nueva versión, que aun no he tenido oportunidad de utilizar.

lunes, mayo 19, 2008

Abrir Documentos de MS Office 2007 con OpenOffice.org 2.4

Para abrir documentos con el formato de open Xml (.docx, xlsx, pptx) con openOffice.org estoy utilizando un convertidor http://katana.oooninja.com/w/odf-converter-integrator, este programa crea una copia del archivo a un formato que OpenOffice.org puede abrir. Hasta ahora todos los archivos que he probado han sido convertidos con calidad.

domingo, marzo 02, 2008

Firebird and DBX4

Although Firebird is not officially supported by the Interbase dbexpress driver it can be used without problems until the BSD 2006 (and the Turbo versions).

Now with Delphi 2007, RAD Studio and DBX4, firebird can still be use with Interbase driver, except if is used on Blobs fields; they allow reading but does not allow updating. This presents a problem when migrate applications to the latest version of Delphi and RAD Studio. This was reported in Quality Central but CodeGear closed the post arguing that Firebird is not Interbase, and the driver was written for Interbase, therefore it’s not a bug.

I suppose Firebird and Interbase will be separating each other more on future versions. I hope CodeGear will develop a driver for firebird because there are many applications made with Delphi and C++ Builder that are using Firebird.

Firebird DBX4 Blob Fields

Aunque Firebird no es oficialmente soportado por el driver de interbase para dbexpress, se puede utilizar sin problemas hasta la versión de BSD 2006 (incluyendo los Turbo).
Ahora con la versión 2007 y DBX4 se puede seguir utilizando el driver de interbase, excepto si se usa campos Blobs. Ya que estos solo pueden ser leídos, pero no pueden ser actualizados. Lo cual representa un problema al querer migrar aplicaciones a la nueva versión de delphi y/o RAD Studio.

"El Problema" fue reportado en Quality Central pero CodeGear cerró el post argumentando que Firebird no es Interbase y el driver fue escritó para Interbase, por lo tanto no es un bug.


Supongo que poco a poco se irán separando cada vez más la base de datos Firebird e Interbase. Ojala y CodeGear desarrolle un driver para firebird ya que muchas de las aplicaciones hechas en delphi y BCB utilizan este servidor SQL.

lunes, febrero 18, 2008

Reiniciar Identity en MS SQL Server

Esto es algo que casi no uso, pero de vez en cuando lo necesito y se me olvida apuntarlo, asi que ahora lo anoto aqui para que no se me olvide:

DBCC CHECKIDENT («Tabla», RESEED, «Semilla»);

por ejemplo reiniciar la semilla en la columna CustomerID en la tabla dbo.Customers seria:

DBCC CHECKIDENT ('dbo.Customers', RESEED, 1);

viernes, febrero 15, 2008

IBExpert

Actualmente estoy usando el servidor SQL Firebird, este motor al ser open source no trae una herramienta de interfaz grafica para administración. Hay varias que se pueden usar, pero la que he encontrado mas facil y que se adapta mas a lo que necesito es IBExpert . Ademas de que tienen una versión personal gratis.