Pregunta

(resuelto: ver abajo)

Tengo el siguiente fragmento de código:

Protected Sub SqlDataSource1_Inserted(ByVal sender As Object, 
ByVal e As System.Web.UI.WebControls.SqlDataSourceStatusEventArgs)
Handles SqlDataSource1.Inserted
    affected = CInt(DirectCast(e.Command.Parameters("@affected"), IDbDataParameter).Value)
    newID = CInt(DirectCast(e.Command.Parameters("@newID"), IDbDataParameter).Value)
End Sub

Donde @newID se define así en la cadena SQL:

"INSERT INTO x(a,b,c) VALUES (@a,@b,@c); SELECT @affected = @@rowcount, @newID = SCOPE_IDENTITY();

Los parámetros se definen usando ASP.NET de la siguiente manera:          

Lo extraño es que esto funciona el 90% del tiempo, pero de vez en cuando arroja una InvalidCastException que dice que "La conversión del tipo 'DBNull' al tipo 'Integer' no es válida". ¿Alguna idea sobre qué podría estar causando que este valor sea nulo? No tengo ningún activador establecido en la tabla, y lo único que está haciendo mi consulta es ejecutar una inserción simple en 1 tabla.

Editar : según las sugerencias aquí, agregué un parámetro afectado . Establecí un punto de interrupción y afecté = 1, pero aún obtuve la excepción. Sin embargo, descubrí que tenía SELECT @newID antes de SELECT @affected. Cambié el orden y ahora @affected = 0. Entonces parece ser un problema con mi declaración de inserción después de todo. ¡Gracias por tu ayuda!

¿Fue útil?

Solución

De MSDN

  

Después de INSERTAR, SELECCIONAR EN, o en masa   se completa la declaración de copia,   @@ IDENTITY contiene la última identidad   valor generado por el   declaración. Si la declaración no lo hizo   afectar cualquier tabla con identidad   columnas, @@ IDENTITY devuelve NULL.

¿Tiene una comprobación para ver si la inserción ha sido exitosa? Es posible que el registro que está intentando insertar no pueda insertar nada por alguna razón, por lo tanto, la identificación es nula.

¿Hay algún desencadenante configurado en la mesa? Es posible que esté recuperando la identificación de un procedimiento de activación utilizando @@ IDENTITY

Sugeriría usar SCOPE_IDENTITY () o un parámetro de salida para obtener la identificación

Otros consejos

Debe usar SCOPE_IDENTITY () en lugar de @@ IDENTITY en el 99.9% de los casos. Es muy raro que tenga una situación que requiera algo más que SCOPE_IDENTITY()

  

@@ IDENTITY devuelve la última IDENTIDAD   valor producido en una conexión,   independientemente de la tabla que produjo   el valor e independientemente del alcance   de la declaración que produjo el   valor. Si tienes un disparador en un   tabla que hace que una identidad sea   creado en otra tabla, obtendrá   la identidad que se creó por última vez,   incluso si fue el desencadenante que   lo creó.

     

SCOPE_IDENTITY () devuelve el último valor IDENTITY producido en un   conexión y por una declaración en el   mismo alcance, independientemente de la tabla   eso produjo el valor.   SCOPE_IDENTITY (), como @@ IDENTITY,   devolverá el último valor de identidad   creado en la sesión actual, pero   también lo limitará a su actual   alcance también.

¿Está seguro de que no hay activadores de auditoría en esa tabla (tal vez agregados por su DBA)?

Varias posibilidades:

  • INSERT no inserta nada (como erikkallen dijo)

  • su declaración (no se muestra) inserta a varias mesas, la última de que no tiene identidad columna

  • el INSERT activa un disparador que se inserta en una mesa sin un columna de identidad - intente SCOPE_IDENTITY () en su lugar

Es posible que desee realizar una verificación para ver si @@ ROWCOUNT > 0.

También hubo problemas conocidos en versiones anteriores de SQL Server con desencadenantes que afectan la capacidad de supervivencia de @@ IDENTITY. ¿Tienes algún desencadenante?

Otra vez cuando esto ocurrió, cambiando

<asp:Parameter Name="newID" Direction="Output" Size="4" />

a

<asp:Parameter Name="newID" Direction="Output" Type="Int32" Size="4" />

solucionó el problema para mí. Al parecer, mi host activó algunos requisitos para una declaración más explícita.

¿Qué es la parte query text ... ? Un INSERTAR, supongo. ¿Podría ser un insert ... select que no encontró ninguna fila?

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