Pregunta

Tengo un script SQL que inserta datos (a través de declaraciones INSERT que actualmente se cuentan por miles). Una de las columnas contiene un identificador único (aunque no un tipo IDENTIDAD, solo un simple int) que en realidad es único en algunas tablas diferentes.

Me gustaría agregar una función escalar a mi script que obtenga la siguiente ID disponible (es decir,ID usado por última vez + 1) pero no estoy seguro de que esto sea posible porque no parece haber una manera de usar una variable global o estática desde una UDF, no puedo usar una tabla temporal y no puedo. Actualizar una tabla permanente desde dentro de una función.

Actualmente mi script se ve así:

   declare @v_baseID int 
   exec dbo.getNextID @v_baseID out  --sproc to get the next available id
   --Lots of these - where n is a hardcoded value
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', @v_baseID + n ) 
   exec dbo.UpdateNextID @v_baseID + lastUsedn  --sproc to update the last used id

Pero me gustaría que se viera así:

   --Lots of these
   insert into tableOfStuff (someStuff, uniqueID) values ('stuff', getNextID() ) 

Codificar el desplazamiento es un dolor de cabeza y es propenso a errores.Empaquetarlo en una función escalar simple es muy atractivo, pero estoy empezando a pensar que no se puede hacer de esa manera ya que no parece haber una manera de mantener el contador de compensación entre llamadas.¿Es así o hay algo que me falta?

Estamos usando SQL Server 2005 en este momento.

ediciones para aclarar:

No sucederá que dos usuarios lo golpeen.Este es un script de actualización que se ejecutará sólo una vez y nunca al mismo tiempo.

El sproc real no tiene el prefijo sp_, se corrigió el código de ejemplo.

En el uso normal, usamos una tabla de identificación y un sproc para obtener las identificaciones según sea necesario, solo estaba buscando una forma más limpia de hacerlo en este script, que esencialmente simplemente descarga un montón de datos en la base de datos.

¿Fue útil?

Solución

Estoy empezando a pensar que no se puede hacer de esa manera ya que no parece haber una manera de mantener el contador de compensación entre llamadas.¿Es así o hay algo que me falta?

No te falta nada;SQL Server no admite variables globales y no admite la modificación de datos dentro de las UDF.E incluso si quisieras hacer algo tan complicado como usar CONTEXT_INFO (ver http://weblogs.sqlteam.com/mladenp/archive/2007/04/23/60185.aspx), de todos modos no puedes configurar eso desde una UDF.

¿Hay alguna manera de evitar la "codificación" del desplazamiento convirtiéndolo en una variable y recorriendo su iteración, haciendo las inserciones dentro de ese bucle?

Otros consejos

Si tiene 2 usuarios que lo presionan al mismo tiempo, obtendrán la misma identificación.¿Por qué no usó una tabla de identificación con una identidad, la insertó en ella y la usó como identificación única (que está garantizada)? Esto también funcionará mucho más rápido.

sp_getNextID

Nunca anteponga procs con sp_, esto tiene implicaciones en el rendimiento porque el optimizador primero verifica la base de datos maestra para ver si ese proceso existe allí y luego en la base de datos local, además, si MS decide crear un sp_getNextID en un paquete de servicio, el suyo nunca se ejecutará.

Probablemente sería más trabajo de lo que vale, pero puede usar variables estáticas de C#/VB en una UDF de SQL CLR, por lo que creo que podría hacer lo que quiera simplemente incrementando esta variable cada vez que se abre la UDF. llamado.La variable estática se perdería cada vez que se descargara el dominio de la aplicación, por supuesto.Entonces, si necesita continuidad de su ID de un día para otro, necesitará una forma, en el primer acceso a NextId, de sondear todas las tablas que usan este ID para encontrar el valor más alto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top