BUG con Sql Server, Asp.NET y un simple Insert Into

20/07/2004 - 02:11 por Diego Arturo Barriguete | Informe spam
El caso es el siguiente y espero que alguien tenga la
solución a este problema :-S

Tengo un programa en ASP.NET (C#), bastante sencillito,
guardo 7 datos por medio de una instrucción insert (la
instrucción la creo en tiempo de ejecución por necesidades
de Flexibilidad), creo mi objeto SqlConnection y el
SqlCommand, para ejecutar la instrucción.

Ahora bien el programa es bastante cristiano "Funciona
cuando Dios quiere" y ya tengo un gran problema por lo
siguiente, al ejecutar la aplicación (en algunas pocas
ocasiones -3 de cada 10 aprox-) genera el siguiente error:

///****Error
Sentencia: insert into funcionariosDatos
(ftitulo,fapellipa,password,fapellima,nivel,usuario,fnombre
) values ('1','Muñoz','here','y
Rojas','2','diegonil','Pablo')
candena: Data Source=LaIPDeMiServidorSQLServer;Initial
Catalog=MiBaseDeDatos;user
id=MiUsuario;password=MiPassword;
Ejecutando una parte
Sentencia: insert into funcionariosDatos
(ftitulo,fapellipa,password,fapellima,nivel,usuario,fnombre
) values ('1','Muñoz','here','y
Rojas','2','diegonil','Pablo')
A la mitad de una parte
Sentencia: insert into funcionariosDatos
(ftitulo,fapellipa,password,fapellima,nivel,usuario,fnombre
) values ('1','Muñoz','here','y
Rojas','2','diegonil','Pablo')
Ocurrió un error al guardar los datos del formulario
Por favor vuelva a realizar la operación o comuniquese con
el encargado del sistema
Error: System.Data.OleDb.OleDbException: Se terminó la
instrucción. Infracción de la restricción PRIMARY
KEY 'PK_procuradorDatos'. No se puede insertar una clave
duplicada en el objeto 'funcionariosDatos'. at
System.Data.OleDb.OleDbDataReader.NextResults
(IMultipleResults imultipleResults, OleDbConnection
connection, OleDbCommand command) at
System.Data.OleDb.OleDbCommand.ExecuteReaderInternal
(CommandBehavior behavior, String method) at
System.Data.OleDb.OleDbCommand.ExecuteNonQuery() at
profedet.CatFuncionarioGuarda.guardarDatosPaginaArgumentos
() in
C:\Inetpub\wwwroot\Modulo_Archivo\aspx\Catalogos\CatalogosC
lases.cs:line 490
Mensaje: Se terminó la instrucción. Infracción de la
restricción PRIMARY KEY 'PK_procuradorDatos'. No se puede
insertar una clave duplicada en el
objeto 'funcionariosDatos'.
///****Fin del Error

Se obtiene este error aunque el registro NO EXISTA EN LA
TABLA. Después de ver el error y revisar la tabla O
SORPRESA, los datos son registrados en la base de datos
sin problema alguno.

Ya limpié la tabla completamente y me sigue generando el
mismo error aunque solamente haya 5 registros. Y TODOS
SEAN DIFERENTES (incluso el de captura)

el código de la función que guarda los datos es la
siguiente:

/////***Aqui esta el Método
public bool guardarDatosPaginaArgumentos()
{
//TDatos,TPropiedades;
string
sentencia,sentenciaAux,sentenciaActualizar;
//ValorAux ayuda a tener un valor en string
para después
//crear la sentencia de actualización necesaria
string valorAux;
DateTime actual;
int agno,numero;
bool respuesta=false;
//El diccionario guarda el nombre del campo
(llave) y su valor
//con el que será actualizado
StringDictionary diccionario;
SqlConnection conexion,conecTemporal;
SqlCommand ejecutor,ejecTemp;
SqlDataReader lector,lectorTemporal;

OleDbConnection conexionOle;
OleDbCommand comandoOle;


obtenerPropiedadesForm();

sentenciaActualizar="";
sentencia="select
idLogico,tipoDato,requerido,componente
from "+TPropiedades+" where IdDocto="+IdDocto+ " and
Pagina="+NAlta;

diccionario=new StringDictionary();
conexion=new SqlConnection(CConexion);
conexion.Open();
ejecutor=null;
try
{
respuesta=true;
//Primero se obtienen todos los datos a
capturar,
//y se guardan en un diccionario de datos
ejecutor=new SqlCommand
(sentencia,conexion);
lector=ejecutor.ExecuteReader();

while (lector.Read())
{
//en caso de recibir un tipo de dato
autonumérico
//se debe de crear el valor necesario
switch(lector.GetInt32(1))
{
case 1:
//Se genera el folio anual
actual=DateTime.Now;
agno=actual.Year;
sentenciaAux="select max(
substring("+ lector.GetString(0) +",1, { fn LENGTH("+
lector.GetString(0)+")} -5 )+0) AS Expr1 FROM "+TDatos
+ " WHERE (SUBSTRING("+ lector.GetString(0) +",{ fn LENGTH
("+ lector.GetString(0) +") } -3, 4)='"+ agno +"')";

conecTemporal=new SqlConnection
(CConexion);
conecTemporal.Open();
ejecTemp=new SqlCommand
(sentenciaAux,conecTemporal);

lectorTemporal=ejecTemp.ExecuteReader();

//Solo se obtendrá un resultado
numero=1;
if (lectorTemporal.Read())//se
encontraron datos
{
if (!
lectorTemporal.IsDBNull(0))//se busca el último número
{

numero=lectorTemporal.GetInt32(0);
numero=numero+1;
}
}

valorAux=numero+"/"+agno;

diccionario.Add
(lector.GetString(0),valorAux);
break;
case 2:
//Como es autonumérico global
y definido desde
//la base de datos no se debe
de agregar al
//diccionario y funcionará de
forma correcta
break;
default:
diccionario.Add
(lector.GetString(0),Request.Form[lector.GetString(0)]);
break;
}
}
lector.Close();
}
catch (Exception falla)
{
Response.Write("<b><br><font
color=ff0000>Ocurrió un error al obtener los datos del
formulario");
Response.Write("<br>Por favor vuelva a
realizar la operación o comuniquese con el encargado del
sistema");
Response.Write("<br>Error: "+falla.ToString
());
Response.Write("<br>Mensaje: "+
falla.Message+"</font></b>");
respuesta=false;
}
finally
{
conexion.Close();
conexion=null;
}

//en caso de haber generado un error la parte
anterior se
//envia una respuesta de error a la aplicación
if (!respuesta)
{
return respuesta;
}

//Se verifican los datos
//Se crea la sentencia necesaria para guardar
los datos en la tabla

sentenciaActualizar=ManipuladorSentencias.creaSentenciaAlta
(TDatos,diccionario);
Response.Write
("<br>Sentencia: "+sentenciaActualizar);
//se guardan los datos en la tabla indicada
//conexion=new SqlConnection(CConexion);
conexionOle=new OleDbConnection
("Provider=SQLOLEDB;"+CConexion);


Response.Write("<br>candena: "+CConexion);
conexionOle.Open();
try
{
Response.Write("<br>Ejecutando una parte");
respuesta=true;
Response.Write
("<br>Sentencia: "+sentenciaActualizar);
//ejecutor=new SqlCommand
(sentenciaActualizar,conexion);
comandoOle= new OleDbCommand
(sentenciaActualizar,conexionOle);

Response.Write("<br>A la mitad de una
parte");

Response.Write
("<br>Sentencia: "+sentenciaActualizar);

comandoOle.ExecuteNonQuery();
Response.Write
("<br>Sentencia: "+sentenciaActualizar);
Response.Write("<br>Finalizando una
parte");
}
catch (Exception falla2)
{

Response.Write("<b><br><font
color=ff0000>Ocurrió un error al guardar los datos del
formulario");
Response.Write("<br>Por favor vuelva a
realizar la operación o comuniquese con el encargado del
sistema");
Response.Write
("<br>Error: "+falla2.ToString());
Response.Write("<br>Mensaje: "+
falla2.Message+"</font></b>");
respuesta=false;
}
finally
{
conexionOle.Close();
}

return respuesta;
}

//************* Hasta aqui debes borrar
}
/////***Hasta Aqui fin del Metodo


La estructura de la base de la tabla es la siguiente:
///Estructura BD
CREATE TABLE [dbo].[funcionariosDatos] (
[fNombre] [varchar] (50) COLLATE
Traditional_Spanish_CI_AS NOT NULL ,
[fApellipa] [varchar] (50) COLLATE
Traditional_Spanish_CI_AS NOT NULL ,
[fApellima] [varchar] (50) COLLATE
Traditional_Spanish_CI_AS NULL ,
[usuario] [varchar] (20) COLLATE
Traditional_Spanish_CI_AS NOT NULL ,
[password] [varchar] (20) COLLATE
Traditional_Spanish_CI_AS NOT NULL ,
[nivel] [int] NOT NULL ,
[fTitulo] [int] NOT NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[funcionariosDatos] WITH NOCHECK ADD
CONSTRAINT [PK_procuradorDatos] PRIMARY KEY
CLUSTERED
(
[usuario]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[funcionariosDatos] ADD
CONSTRAINT [FK_funcionariosDatos_catTitulo]
FOREIGN KEY
(
[fTitulo]
) REFERENCES [dbo].[catTitulo] (
[idTitulo]
),
CONSTRAINT [FK_funcionariosDatos_nivelDatos]
FOREIGN KEY
(
[nivel]
) REFERENCES [dbo].[nivelDatos] (
[idNivel]
)
GO
///Estructura BD


OK, pues finalmente ya estoy hasta el gorro de este error
tan chafa, se podría decir que el código se ejecuta dos
veces para que suceda esto, pero por que hay ocasiones en
que si lo hace sin presentar error alguno y otras
ocasiones en que sucede todo lo contrario. Incluso ya he
registrado la información que me genera el error y en
ocasiones muestra el error y en otras no, aunque cabe
resaltar que con mensaje de error o sin el LA INFORMACION
SE GUARDA SIN PROBLEMA ALGUNO. yo digo que la excepción
esta siendo arrojada por un motivo ageno a mi insert.

Saludos a todos y a ver si alguien puede con este error :-|
 

Leer las respuestas

#1 Misael Monterroca
20/07/2004 - 17:29 | Informe spam
Esta un poco largo tu código como para leerlo completo :)

Pero de casualidad no estaras de alguna manera insertando dos veces el
mismo registro, es la única razón que se me ocurre ya que comentas que si
ves la información que existe en la base de datos, por que no podes un
breakpoint y analizas la información que acabas de ingresar.

Otra opción, es que para fines de prueba deshabilites tu llave primaria y
corras tu aplicación verificando que efectivamente no se este guardando en
la BD dos veces el registro.

Saludos!
http://cacho.zapto.org/blog




"Diego Arturo Barriguete" wrote in message
news:031201c46dee$17ba35e0$
El caso es el siguiente y espero que alguien tenga la
solución a este problema :-S

Tengo un programa en ASP.NET (C#), bastante sencillito,
guardo 7 datos por medio de una instrucción insert (la
instrucción la creo en tiempo de ejecución por necesidades
de Flexibilidad), creo mi objeto SqlConnection y el
SqlCommand, para ejecutar la instrucción.

Preguntas similares