7

He iniciado sesión en una base de datos de SQL Server 2005 como un usuario no sa, 'bhk', que es miembro de la función de servidor 'público' solamente. El siguiente código intenta ejecutarse dentro de un procedimiento almacenado llamado por el usuario 'bhk'. Esta línea de código ...DBCC CHECKIDENT en una tabla temporal arrojando errores de permisos para el usuario incorrecto

TRUNCATE TABLE #Table1 
DBCC CHECKIDENT('#Table1', RESEED, @SequenceNumber) WITH NO_INFOMSGS 

causas de este error ...

usuario 'invitado' no tiene permiso para ejecutar DBCC CHECKIDENT por objeto
'# Table1__00000000007F'.

Soy consciente de los permisos necesarios para ejecutar DBCC CHECKIDENT ...
persona que llama debe poseer la tabla, o ser un miembro de la función fija de servidor sysadmin, la función de base de datos fija db_owner, o la función de base de datos fija db_ddladmin.

así que tengo dos preguntas:

  1. Desde 'BHK' se llama a un procedimiento almacenado que crea una tabla temporal , no debe 'BHK' ser el propietario y se le permitirá ejecutar DBCC ¿CHECKIDENT?
  2. ¿Por qué el mensaje de error devuelve que el usuario 'invitado' no tiene permiso? Que yo sepa, no estoy conectado como 'invitado'.

Cualquier ayuda sería muy apreciada.

Respuesta

6

Aquí es una solución alternativa, que puede funcionar si es necesario volver a la semilla con un número de secuencia de más de 1.

TRUNCATE #Table1 

SET IDENTITY_INSERT #Table1 ON 

INSERT INTO #Table1 (TableID) -- This is your primary key field 
VALUES (@SequenceNumber - 1) 

SET IDENTITY_INSERT #Table1 OFF 

DELETE FROM #Table1 

Lo que esto hace es fijar el IDENTITY_INSERT en su tabla temporal, para permitirle agregar una fila con una ID explícita. A continuación, puede eliminar esta fila, pero las inserciones adicionales deben comenzar desde el último número de secuencia.

3

Usted escribió:

"de llamadas debe ser propietario de la tabla, o ser un miembro de la sysadmin función de servidor , el db_owner."

Entonces (si no es un error), según Lieutenant Columbo's lógica impecable, cada una de las premisas debe ser falsa. Eso significa que la persona que llama no posee la tabla,, incluso si la creó.

De hecho, parece que todos los objetos creados en tempd son propiedad de dbo de forma predeterminada. Puede examinarlo, si siguiente en el Analizador de consultas:

  1. Conectar a la base de datos utilizando el usuario bajo permiso.
  2. ejecutar: CREATE TABLE #NotMyTable (TestID int identity)
  3. Conectar a tempdb del mismo SQL Server como DBO
  4. ejecutar: SELECT user_name(uid) FROM sysobjects WHERE name LIKE '#NotMyTable%'

Verás que dbo es el propietario de la tabla temporal.

Por lo tanto, lo que podría ser una solución?

(Prólogo: no me gusta ese tipo de manipulación, pero el estímulo intelectual me está volviendo ... ;-))

Por lo tanto, se podría escribir otro procedimiento almacenado que actualiza el UID en sysobjects del tempdb al valor de su usuario (shiver!). Lo probé solo en el Analizador de consultas. Después de la Actualización, podría ejecutar su comando DBCC CHECKIDENT.

+0

Si bien esto probablemente funcione, estoy de acuerdo con que no me gusta ese tipo de manipulación. –

1

Una solución alternativa para hacer los comandos TRUNCATE y CHECKIDENT sería simplemente quitar y volver a crear la tabla temporal. P.ej.

DROP TABLE #Table1 

CREATE TABLE #Table1 
(
    .... 
) 

Sin embargo, esta puede no ser la solución más eficiente.

+0

Tiene razón. Sin embargo, en mi situación, el objetivo es restablecer la columna de identidad a algo que no sea 1. Drop/Create solo restablecería la columna a 1 y no parece permitir variables como un valor para el parámetro IDENTITY SEED. –

2

Puede lograr esto calificando completamente la tabla tempdb.

DBCC CHECKIDENT([tempdb..#Table1], RESEED, @SequenceNumber) WITH NO_INFOMSGS 
1

Acabo de toparme con esto. La respuesta a la que llegué fue darle a la cuenta relevante los permisos en la base de datos tempdb donde, aparentemente, se crearon estas tablas.

+0

He resuelto este problema iniciando sesión como sa y comprobando el inicio de sesión que estaba utilizando para asegurarme de que tenía un usuario mapeado en tempdb que tenía membresía en ddladmin – jocassid

Cuestiones relacionadas