Adán, parte de este gran equipo de trabajo, nos ha hecho el favor de crear este tutorial ya que domina a la perfección este tema.
Solución:
Tu podrías intentar
SET IDENTITY_INSERT #Tmp_MyTable ON
-- ... do stuff
SET IDENTITY_INSERT #Tmp_MyTable OFF
Esto le permitirá seleccionar en #Tmp_MyTable
aunque tiene una columna de identidad.
Pero esto no lo haré trabaja:
-- Create empty temp table
SELECT *
INTO #Tmp_MyTable
FROM MyTable
WHERE 1=0
...
WHILE ...
BEGIN
...
SET IDENTITY_INSERT #Tmp_MyTable ON
INSERT INTO #Tmp_MyTable
SELECT TOP (@n) *
FROM MyTable
SET IDENTITY_INSERT #Tmp_MyTable OFF
...
END
(Resulta en el error “Solo se puede especificar un valor explícito para la columna de identidad en la tabla ‘#Tmp’ cuando se usa una lista de columnas y IDENTITY_INSERT está activado”).
Parece que no hay forma de no dejar caer la columna, pero eso cambiaría el orden de las columnas como mencionó OP. Truco feo: crea una nueva tabla basada en #Tmp_MyTable…
Le sugiero que escriba un procedimiento almacenado que cree una tabla temporal basada en un nombre de tabla (MyTable
) con las mismas columnas (en orden), pero sin la propiedad de identidad.
Podrías usar el siguiente código:
select t.name as tablename, typ.name as typename, c.*
from sys.columns c inner join
sys.tables t on c.object_id = t.[object_id] inner join
sys.types typ on c.system_type_id = typ.system_type_id
order by t.name, c.column_id
para echar un vistazo a cómo funciona la reflexión en TSQL. Creo que tendrá que recorrer las columnas de la tabla en cuestión y ejecutar declaraciones de modificación dinámicas (hechas a mano, almacenadas en cadenas y luego evaluadas) en la tabla generada.
¿Le importaría publicar un procedimiento almacenado de este tipo para el resto del mundo? Esta pregunta parece surgir bastante en otros foros también…
SI solo está procesando filas como lo describe, ¿no sería mejor simplemente seleccionar las N principales primarias? key valores en una tabla temporal como:
CREATE TABLE #KeysToProcess
(
TempID int not null primary key identity(1,1)
,YourKey1 int not null
,YourKey2 int not null
)
INSERT INTO #KeysToProcess (YourKey1,YourKey2)
SELECT TOP n YourKey1,YourKey2 FROM MyTable
Él keys no debería cambiar muy a menudo (espero) pero otras columnas pueden hacerlo sin daño al hacerlo de esta manera.
obtenga el @@ROWCOUNT de la inserción y puede hacer un bucle fácil en TempID donde será de 1 a @@ROWCOUNT
y/o
simplemente agregue #KeysToProcess a su tabla MyKeys y siga su camino, sin necesidad de duplicar todos los datos.
Esto funciona bien en mi SQL Server 2005, donde MyTable.MyKey es una columna de identidad.
-- Create empty temp table
SELECT *
INTO #TmpMikeMike
FROM (SELECT
m1.*
FROM MyTable m1
LEFT OUTER JOIN MyTable m2 ON m1.MyKey=m2.MyKey
WHERE 1=0
) dt
INSERT INTO #TmpMike
SELECT TOP 1 * FROM MyTable
SELECT * from #TmpMike
EDITAR
ESTO FUNCIONA, sin errores…
-- Create empty temp table
SELECT *
INTO #Tmp_MyTable
FROM (SELECT
m1.*
FROM MyTable m1
LEFT OUTER JOIN MyTable m2 ON m1.KeyValue=m2.KeyValue
WHERE 1=0
) dt
...
WHILE ...
BEGIN
...
INSERT INTO #Tmp_MyTable
SELECT TOP (@n) *
FROM MyTable
...
END
sin embargo, ¿cuál es tu verdadero problema? ¿Por qué necesita hacer un bucle al insertar “*” en esta tabla temporal? Es posible que pueda cambiar la estrategia y crear un algoritmo mucho mejor en general.
Si te sientes suscitado, eres capaz de dejar un artículo acerca de qué te ha gustado de este escrito.