2011-11-23 19 views
9

Esto no ejecuta:¿Por qué no puede usar SQLite ROWID como clave principal?

create table TestTable (name text, age integer, primary key (ROWID)) 

El mensaje de error es:

11-23 11: 05: 05,298: ERROR/Base de datos (31335): Si no 1 (tabla TestTable no tiene una columna llamada ROWID) en 0x2ab378 al preparar 'create table TestTable (nombre del texto, número entero de la edad, clave principal (ROWID))'.

Sin embargo, una vez creada la TestTable, esto prepara y ejecuta bien:

create table TestTable (name text, age integer); 

insert into TestTable (name, age) values ('Styler', 27); 

select * from TestTable where ROWID=1; 

que podía potencialmente ver ROWID como una solución a la necesidad de una clave primaria incremento automático y clave externa que son nunca va a ser utilizado tan poblado como datos en la capa de aplicación. Como ROWID está oculto de los conjuntos de resultados select de forma predeterminada, hubiera sido bueno asociar esto con la clave principal mientras se mantiene oculta de la lógica de la aplicación. OracleBlog: ROWNUM and ROWID dicen que esto es imposible y desaconsejable, pero no ofrece muchas otras explicaciones aparte de eso.

Así que, dado que la respuesta a "¿es esto posible?" Es definitivamente no/desaconsejable, la pregunta es más o menos "¿por qué no?

+1

ROWNUM cambia cada vez que se actualiza el registro, ROWID cambia según el orden o el orden de su conjunto de resultados. Así que RowNum es malo porque tendrías que actualizar todas las claves externas cada vez que se realiza un cambio en el maestro. (mucha sobrecarga) y ROWID es malo porque la ID no existe hasta que se crea y se ordena el conjunto de resultados. Si no existe, no puedes unirte a él. – xQbert

+0

@xQbert si se hace referencia a ROWID con una clave principal, ¿cómo cambiaría en función del orden de las columnas en el conjunto de resultados? – styler1972

+0

ROWID no existe en su tabla describe testtable. Verás que ROWID no está allí. ROWID es una columna del sistema y un valor mantenido por el sistema. no puede tener un PK en una columna del sistema; usted no tiene los permisos para hacerlo. Sobre lo anterior: lo tengo al revés; ROWID puede cambiar en función de la actualización frente a ROWNUM, que cambia según la selección de cláusula. – xQbert

Respuesta

28

De SQLite.org:

Si una tabla contiene una columna de tipo INTEGER PRIMARY KEY, a continuación, que columna se convierte en un alias para el ROWID. A continuación, puede acceder al ROWID utilizando cualquiera de los cuatro nombres diferentes, los tres nombres originales descritos arriba o el nombre dado a la columna INTEGER PRIMARY KEY. Todos estos nombres son alias uno para el otro y funcionan igual de bien en cualquier contexto .

Simplemente utilícelo como clave principal.

+1

Al agregar cualquier clave primaria de incremento automático, esencialmente estoy usando ROWID como clave principal. Estaba pensando que ya que era así de fácil, podía declarar al rowid como primario. Obviamente hay un poco más de cosas que eso. Eso es lo que obtengo por pensar diferente, lástima de mí: D – styler1972

+2

[Agregar una clave de autoincremento cambia ligeramente el comportamiento] (http://www.sqlite.org/autoinc.html). El ROWID no siempre es adecuado, principalmente si los valores monótonamente crecientes son un requisito. – user2864740

Cuestiones relacionadas