Oharra
Orrialde honetara sartzeak baimena behar du. Saioa hasteko edo direktorioak aldatzen saia zaitezke.
Orrialde honetara sartzeak baimena behar du. Direktorioak aldatzen saia zaitezke.
Se aplica a:SQL Server
Azure SQL Database
Instancia
administrada de Azure SQLBase de datos SQL en Microsoft Fabric
En este artículo se explica cómo usar números de secuencia en SQL Server, Azure SQL Database e Instancia administrada de Azure SQL. Una secuencia es un objeto enlazado a un esquema definido por el usuario que genera una secuencia de valores numéricos según la especificación con la que se creó la secuencia.
Información general
La secuencia de valores numéricos se genera en orden ascendente o descendente en un intervalo definido y puede repetirse cuando se solicite. Las secuencias, a diferencia de las columnas de identidad, no están asociadas a las tablas. Una aplicación hace referencia a un objeto de secuencia para recibir su valor siguiente. La aplicación controla la relación entre las secuencias y tablas. Las aplicaciones de usuario pueden hacer referencia a un objeto de secuencia y coordinar las claves de valores entre varias filas y tablas.
Una secuencia se crea independientemente de las tablas mediante la CREATE SEQUENCE instrucción . Las opciones permiten controlar el incremento, los valores máximo y mínimo, el punto de inicio, la capacidad de reinicio automático y el almacenamiento en caché para aumentar el rendimiento. Para obtener información acerca de las opciones, vea CREATE SEQUENCE.
A diferencia de los valores de columnas de identidad que se generan cuando se insertan filas, una aplicación puede obtener el número de secuencia siguiente sin insertar la fila llamando a la función NEXT VALUE FOR . El número de secuencia se asigna cuando NEXT VALUE FOR se llama, aunque el número nunca se inserte en una tabla. La NEXT VALUE FOR función se puede usar como valor predeterminado para una columna en una definición de tabla. Use sp_sequence_get_range para obtener un rango de varios números de secuencia de una sola vez.
Una secuencia se puede definir como cualquier tipo de datos enteros. Si no se especifica el tipo de datos, una secuencia tiene como valor predeterminado bigint.
Uso de secuencias
Utilice secuencias en lugar de columnas de identidad en los siguientes escenarios:
La aplicación requiere un número antes de realizar la inserción en la tabla.
La aplicación requiere compartir una serie única de números entre varias tablas o varias columnas de una tabla.
La aplicación debe reiniciar la serie de números cuando se alcanza un número especificado. Por ejemplo, después de asignar valores entre 1 y 10, la aplicación comienza de nuevo a asignar valores entre 1 y 10.
La aplicación requiere que los valores de secuencia se ordenen por otro campo. La
NEXT VALUE FORfunción puede aplicar laOVERcláusula a la llamada de función. La cláusulaOVERgarantiza que los valores devueltos se generan en el orden de la cláusulaOVERORDER BY.Una aplicación requiere que se asignen varios números al mismo tiempo. Por ejemplo, una aplicación necesita reservar cinco números secuenciales. Al solicitar los valores de identidad, podrían producirse lagunas en la serie si se emitieron números simultáneamente para otros procesos. Al llamar a
sp_sequence_get_rangese pueden recuperar de una sola vez varios números de la secuencia.Necesita cambiar la especificación de la secuencia, como, por ejemplo, el valor de incremento.
Limitaciones
A diferencia de las columnas de identidad, cuyos valores no se pueden cambiar, los valores de secuencia no se protegen automáticamente después de la inserción en la tabla. Para evitar que se cambien los valores de secuencia, utilice un desencadenador de actualización en la tabla para revertir los cambios.
La unicidad no se aplica automáticamente a los valores de secuencia. La capacidad de reutilizar los valores de secuencia es por diseño. Si es necesario que los valores de secuencia de una tabla sean únicos, cree una restricción única en la columna. Si se requiere que los valores de secuencia de una tabla sean únicos en todo un grupo de tablas, cree desencadenadores para evitar los duplicados debidos a las instrucciones de actualización o al ciclo del número de secuencia
El objeto de secuencia genera números según su definición, pero el objeto de secuencia no controla cómo se usan los números. Los números de secuencia insertados en una tabla pueden tener lagunas cuando se revierte una transacción, cuando varias tablas comparten un objeto de secuencia o cuando los números de secuencia se asignan sin utilizarlos en tablas. Cuando se crea con la CACHE opción , un apagado inesperado, como un error de energía, puede perder los números de secuencia en la memoria caché.
Si hay varias instancias de la NEXT VALUE FOR función que especifican el mismo generador de secuencia dentro de una sola instrucción Transact-SQL, todas esas instancias devuelven el mismo valor para una fila determinada procesada por esa instrucción Transact-SQL. Este comportamiento es coherente con el estándar ANSI.
Los números de secuencia se generan fuera del ámbito de la transacción actual. Se consumen si la transacción que usa el número de secuencia se confirma o se revierte. La validación de duplicados solo se produce una vez que un registro está totalmente relleno. Esto puede dar lugar a casos en que se use el mismo número para más de un registro durante la creación, pero luego se identifique como un duplicado. Si ocurre esto y se han aplicado otros valores autonuméricos a sucesivos registros, esta situación puede dar lugar a una discrepancia entre los valores autonuméricos.
Uso típico
Para crear un número de secuencia entero que se incremente en 1 de -2.147.483.648 a 2.147.483.647, utilice la siguiente instrucción.
CREATE SEQUENCE Schema.SequenceName
AS INT
INCREMENT BY 1;
Para crear un número de secuencia entero similar a una columna de identidad que se incrementa en 1 de 1 a 2.147.483.647, utilice la siguiente instrucción.
CREATE SEQUENCE Schema.SequenceName
AS INT
START WITH 1
INCREMENT BY 1;
Administrar secuencias
Para obtener información sobre las secuencias, consulte sys.sequences.
Ejemplos
Hay más ejemplos en los artículos CREATE SEQUENCE, NEXT VALUE FOR y sp_sequence_get_range.
A Uso de un número de secuencia en una sola tabla
En el ejemplo siguiente se crea un esquema denominado Test, una tabla denominada Orders y una secuencia denominada CountBy1y, a continuación, se insertan filas en la tabla mediante la NEXT VALUE FOR función .
CREATE SCHEMA Test;
GO
CREATE TABLE Test.Orders
(
OrderID INT PRIMARY KEY,
Name VARCHAR (20) NOT NULL,
Qty INT NOT NULL
);
GO
CREATE SEQUENCE Test.CountBy1
START WITH 1
INCREMENT BY 1;
GO
INSERT Test.Orders (OrderID, Name, Qty)
VALUES (NEXT VALUE FOR Test.CountBy1, 'Tire', 2);
INSERT test.Orders (OrderID, Name, Qty)
VALUES (NEXT VALUE FOR Test.CountBy1, 'Seat', 1);
INSERT test.Orders (OrderID, Name, Qty)
VALUES (NEXT VALUE FOR Test.CountBy1, 'Brake', 1);
SELECT *
FROM Test.Orders;
Este es el conjunto de resultados.
OrderID Name Qty
-------- ------ ---
1 Tire 2
2 Seat 1
3 Brake 1
B. Llame al siguiente valor antes de insertar una fila.
Con la tabla creada en el Orders ejemplo A, en el ejemplo siguiente se declara una variable denominada @nextIDy, a continuación, se usa la NEXT VALUE FOR función para establecer la variable en el siguiente número de secuencia disponible. Se supone que la aplicación realiza cierto procesamiento del pedido, como, por ejemplo, proporcionar al cliente el número de OrderID de su pedido potencial y, a continuación, valida el pedido. Con independencia de cuánto tiempo pueda llevar este procesamiento y de cuántos pedidos se agreguen durante el proceso, el número original se conserva para que lo utilice esta conexión. Finalmente, la instrucción INSERT agrega el pedido a la tabla Orders .
DECLARE @NextID AS INT;
SET @NextID = NEXT VALUE FOR Test.CountBy1;
INSERT Test.Orders (OrderID, Name, Qty)
VALUES (@NextID, 'Rim', 2);
C. Uso de un número de secuencia en varias tablas
En este ejemplo se supone que un proceso de supervisión de la línea de producción recibe una notificación de los eventos que se producen en el taller. Cada evento recibe un número EventID único que se incrementa de forma continua. Todos los eventos utilizan el mismo número de secuencia EventID para que los informes que combinan todos los eventos puedan identificar cada evento de forma única. Sin embargo, los datos de evento se almacenan en tres tablas diferentes, dependiendo del tipo de evento. El ejemplo de código crea un esquema denominado Audit, una secuencia denominada EventCountery tres tablas, cada una de las cuales utiliza la secuencia EventCounter como valor predeterminado. A continuación el ejemplo agrega las filas a las tres tablas y consulta los resultados.
CREATE SCHEMA Audit;
GO
CREATE SEQUENCE Audit.EventCounter
AS INT
START WITH 1
INCREMENT BY 1;
GO
CREATE TABLE Audit.ProcessEvents
(
EventID INT DEFAULT ( NEXT VALUE FOR Audit.EventCounter) PRIMARY KEY CLUSTERED,
EventTime DATETIME DEFAULT (getdate()) NOT NULL,
EventCode NVARCHAR (5) NOT NULL,
Description NVARCHAR (300) NULL
);
GO
CREATE TABLE Audit.ErrorEvents
(
EventID INT DEFAULT ( NEXT VALUE FOR Audit.EventCounter) PRIMARY KEY CLUSTERED,
EventTime DATETIME DEFAULT (getdate()) NOT NULL,
EquipmentID INT NULL,
ErrorNumber INT NOT NULL,
EventDesc NVARCHAR (256) NULL
);
GO
CREATE TABLE Audit.StartStopEvents
(
EventID INT DEFAULT ( NEXT VALUE FOR Audit.EventCounter) PRIMARY KEY CLUSTERED,
EventTime DATETIME DEFAULT (getdate()) NOT NULL,
EquipmentID INT NOT NULL,
StartOrStop BIT NOT NULL
);
GO
INSERT Audit.StartStopEvents (EquipmentID, StartOrStop)
VALUES (248, 0);
INSERT Audit.StartStopEvents (EquipmentID, StartOrStop)
VALUES (72, 0);
INSERT Audit.ProcessEvents (EventCode, Description)
VALUES (2735, 'Clean room temperature 18 degrees C.');
INSERT Audit.ProcessEvents (EventCode, Description)
VALUES (18, 'Spin rate threshold exceeded.');
INSERT Audit.ErrorEvents (EquipmentID, ErrorNumber, EventDesc)
VALUES (248, 82, 'Feeder jam');
INSERT Audit.StartStopEvents (EquipmentID, StartOrStop)
VALUES (248, 1);
INSERT Audit.ProcessEvents (EventCode, Description)
VALUES (1841, 'Central feed in bypass mode.');
SELECT EventID,
EventTime,
Description
FROM Audit.ProcessEvents
UNION
SELECT EventID,
EventTime,
EventDesc
FROM Audit.ErrorEvents
UNION
SELECT EventID,
EventTime,
CASE StartOrStop WHEN 0 THEN 'Start' ELSE 'Stop' END
FROM Audit.StartStopEvents
ORDER BY EventID;
Este es el conjunto de resultados.
EventID EventTime Description
----------- ----------------------- ------------------------------------
1 2025-12-09 17:41:57.350 Start
2 2025-12-09 17:41:57.350 Start
3 2025-12-09 17:41:57.350 Clean room temperature 18 degrees C.
4 2025-12-09 17:41:57.350 Spin rate threshold exceeded.
5 2025-12-09 17:41:57.350 Feeder jam
6 2025-12-09 17:41:57.350 Stop
7 2025-12-09 17:41:57.350 Central feed in bypass mode.
D. Generar números de secuencia repetitivos en un conjunto de resultados
En el siguiente ejemplo se muestran dos características de los números de secuencia: recorrer y utilizar NEXT VALUE FOR en una instrucción SELECT.
CREATE SEQUENCE CountBy5
AS TINYINT
START WITH 1
INCREMENT BY 1
MINVALUE 1
MAXVALUE 5
CYCLE;
GO
SELECT NEXT VALUE FOR CountBy5 AS SurveyGroup,
Name
FROM sys.objects;
E. Generación de números de secuencia para un conjunto de resultados mediante la cláusula OVER
En el ejemplo siguiente se utiliza la cláusula OVER para ordenar el conjunto de resultados por Name antes de agregar la columna de número de secuencia.
USE AdventureWorks2022;
GO
CREATE SCHEMA Samples;
GO
CREATE SEQUENCE Samples.IDLabel
AS TINYINT
START WITH 1
INCREMENT BY 1;
GO
SELECT NEXT VALUE FOR Samples.IDLabel OVER (ORDER BY Name) AS NutID,
ProductID,
Name,
ProductNumber
FROM Production.Product
WHERE Name LIKE '%nut%';
F. Restablecer el número de secuencia
El ejemplo E consumió los primeros 79 números de secuencia de Samples.IDLabel. (Su versión de AdventureWorks2025 puede devolver un número de resultados diferente). Ejecute lo siguiente para consumir los 79 números de secuencia siguientes (del 80 al 158).
SELECT NEXT VALUE FOR Samples.IDLabel OVER (ORDER BY Name) AS NutID,
ProductID,
Name,
ProductNumber
FROM Production.Product
WHERE Name LIKE '%nut%';
Ejecute la instrucción siguiente para reiniciar la secuencia Samples.IDLabel .
ALTER SEQUENCE Samples.IDLabel
RESTART WITH 1;
Ejecute la instrucción SELECT de nuevo para comprobar que la secuencia Samples.IDLabel se ha reiniciado con el número 1.
SELECT NEXT VALUE FOR Samples.IDLabel OVER (ORDER BY Name) AS NutID,
ProductID,
Name,
ProductNumber
FROM Production.Product
WHERE Name LIKE '%nut%';
G. Cambio de una tabla de identidad a secuencia
En el siguiente ejemplo se crean un esquema y una tabla que contiene tres filas para el ejemplo. A continuación el ejemplo agrega una nueva columna y quita la columna anterior.
CREATE SCHEMA Test;
GO
CREATE TABLE Test.Department
(
DepartmentID SMALLINT IDENTITY (1, 1) NOT NULL,
Name NVARCHAR (100) NOT NULL,
GroupName NVARCHAR (100) NOT NULL CONSTRAINT PK_Department_DepartmentID PRIMARY KEY CLUSTERED (DepartmentID ASC)
);
GO
INSERT Test.Department (Name, GroupName)
VALUES ('Engineering', 'Research and Development');
GO
INSERT Test.Department (Name, GroupName)
VALUES ('Tool Design', 'Research and Development');
GO
INSERT Test.Department (Name, GroupName)
VALUES ('Sales', 'Sales and Marketing');
GO
SELECT *
FROM Test.Department;
GO
ALTER TABLE Test.Department
ADD DepartmentIDNew SMALLINT NULL;
GO
UPDATE Test.Department
SET DepartmentIDNew = DepartmentID;
GO
ALTER TABLE Test.Department DROP CONSTRAINT [PK_Department_DepartmentID];
ALTER TABLE Test.Department DROP COLUMN DepartmentID;
GO
EXECUTE sp_rename 'Test.Department.DepartmentIDNew', 'DepartmentID', 'COLUMN';
GO
ALTER TABLE Test.Department ALTER COLUMN DepartmentID SMALLINT NOT NULL;
ALTER TABLE Test.Department
ADD CONSTRAINT PK_Department_DepartmentID PRIMARY KEY CLUSTERED (DepartmentID ASC);
SELECT MAX(DepartmentID)
FROM Test.Department;
CREATE SEQUENCE Test.DeptSeq
AS SMALLINT
START WITH 4
INCREMENT BY 1;
GO
ALTER TABLE Test.Department
ADD CONSTRAINT DefSequence DEFAULT ( NEXT VALUE FOR Test.DeptSeq) FOR DepartmentID;
GO
SELECT DepartmentID,
Name,
GroupName
FROM Test.Department;
INSERT Test.Department (Name, GroupName)
VALUES ('Audit', 'Quality Assurance');
GO
SELECT DepartmentID,
Name,
GroupName
FROM Test.Department;
Las instrucciones de Transact-SQL que usan SELECT * reciben como última columna la nueva columna en lugar de la primera. Si esto no es aceptable, debe crear una tabla completamente nueva, mover los datos a ella y volver a crear los permisos en la nueva tabla.