La funcion o procedimiento xxx tiene demasiados argumentos

<MODE masoquista ON>

Mi parte masoquista ha querido que me dedique este fin de semana a una labor dolorosa (supongo que habré sido un chico malo).

Estos días disfruto creando (más bien mejorando, pues está ya hecha) una aplicación web que utilizo personalmente en cada momento para organizar mi trabajo (y mi vida). Pequeños retoques por aquí y allá, que me cuestan un cuarto de hora y que hacen que la aplicación sea todavía más bonita y más eficaz. Un placer.

Pues no. Este fin de semana va a ser diferente y voy a cambiar el diseño de la base de datos, y después voy a cambiar todas mis SQL por procedimientos almacenados y después voy a …. Quizás un trabajo necesario para poder seguir adelante más rápidamente pero, un suplicio para un fin de semana que debe ser para disfrutar. ¡Maldita lluvia, siempre presente! ¡Maldito sol, siempre ausente!

Bueno, pues si después de todos los cambios de mis formularios y módulos para adaptarme al nuevo diseño de la base de datos, no había tenido ya suficiente castigo, cojo el primer formulario (tiene una GridView asociada a un SqlDataSource) y sustituyo las SQL por procedimientos almacenados y empiezo a probar: la visualización va bien, creo un nuevo registro a la primera, pero al borrar o actualizar una línea de la grid me encuentro con el error: «La función o procedimiento xxx tiene demasiados argumentos«. 

Y no hay manera de evitarlo: repaso los argumentos creados para la Delete y la Update, pero están bien; busco en Internet y no encuentro una buena solución; programo unos eventos _Deleting y _Updating y tampoco consigo evitar el error; hago debug con estos eventos y puedo ver que realmente tengo 5 parámetros en la Delete, cuando yo sólo he creado uno.

Al final descubrí que el causante de la creación fantasma de los parámetros no deseados es el argumento de la SqlDataSource llamado ConflictDetection, que puede tener dos valores (CompareAllValues u OverwriteChanges) y yo tenía puesto el primero, que hace, para evitar conflictos al borrar o modificar un registro, comparar todos los valores y no sólo la clave que yo he puesto como parámetro del procedimiento almacenado y por eso crea automáticamente parámetros para poder comparar más campos, que naturalmente yo no había añadido a mi procedimiento almacenado.

Así que si queremos utilizar procedimientos almacenados en un SqlDataSource con los parámetros que nosotros queramos y sólo con ellos, deberemos poner ConflictDetectionOverwriteChanges«.

Quizás la buena práctica sea en estos casos comparar todos los valores en caso de conflicto, pero si queremos ser dueños de nuestros procedimientos almacenados debemos tener en cuenta este argumento ConflictDetection.

Supongo que, para aumento de mi humillación, esto será ya conocido por todo el mundo y con este artículo no haré mas que demostrar mi poco nivel.

Ni siquiera ha levantado mi moral el leer el artículo 10 razones para salir con un Geek.

<MODE masoquista OFF>

11 comentarios sobre “La funcion o procedimiento xxx tiene demasiados argumentos”

  1. Gracias viejo, yo también tuve ese problema y la verdad que estaba dando via, pero = así son las cosas en este negocio.
    Tu blog me ayudo mucho ya que al leerlo razzzzz me diste la receta de cocina.
    Muchas gracias nuevamente.

  2. Hola me aparece el mismo problema, recien empíezo en esto del visual.net y no se donde colocar el ConflictDetection=»OverwriteChanges», me puedes ayudar porfavor

  3. Yo tambien modifique esa propiedad y me sigue saltando el mismo error. Ya no se que hacer. Siempre queda ejecutar el stored via código… pero si eso es un bug (y no mi propia estupidez) me pareze muy grave 🙂

  4. A mi me paso lo mismo, sin embargo el problema se presenta debido al comportamiento de los DataKeyName del GridView con el SqlDataSource. Observad lo que dice la documentación de Microsoft:
    http://msdn.microsoft.com/es-es/library/system.web.ui.webcontrols.gridview.datakeynames(VS.80).aspx

    La documentación dice:
    «Debe establecer la propiedad DataKeyNames para que funcionen las características de actualización y eliminación automática del control GridView. Los valores de estos campos de clave se pasan al control de origen de datos para compararlos con los de la fila que se va a actualizar o eliminar.»

    Lo que implica que los valores de los DataKeyNames que se tengan asociados son los que se le pasaran al procedimiento almacenado. Lo que hay que hacer es en el manejador de eventos Deleting del SqlDataSource eliminar el parametro que no queremos que vaya al procedimiento almacenado. La eliminacion se hace asi:

    Dim paramIdEmpresa As DbParameter = e.Command.Parameters(«@idEmpresa»)
    e.Command.Parameters.Remove(paramIdEmpresa)

  5. Hola, esto mismo me paso a mi, en mi caso yo cargaba la grilla en el load de la pagina mediante una funcion que contenía un sqldatasorce, entonces cada vez que la pagina hiciera postback creaba los parámetros ya sea de inserción o actualización etc.. lo mejor para este caso es antes de agregar los parametros deben hacer una limpieza a estos con la siguiente linea «NombreSqlDatasource.InsertParameters.Clear()» y así mismo con los otros parámetros de selección, eliminación y actualización y verán que funciona.

  6. Muchas veces puede ser que le estemos enviado de mas parametros a nuesto procedimiento almacenado, hay que ver esa parte tambien saludos….

  7. Oie!!! Muchas GraCias,
    puse ConflictDetection=»OverwriteChanges» y modificando el UpdateCommand junto con el ya no me pidio todo la fila india de parametros que originalmente pide con ConflictDetection=»CompareAllValues».
    One kiss !!

  8. Esto yo lo solucione limpiando el sqlCommand.Parameters(), de esta fomra «sqlComman.Parameters.Clear()»,
    obvio antes de agregar el valor a los parametros que seria
    sqlCommand.Parameters.Add(«@variable»,SqlDbType.Char).Value = valorvar

    ejemplo:

    ‘Limpio
    sqlComman.Parameters.Clear()
    ‘Agrego parametros
    sqlCommand.Parameters.Add(«@variable»,SqlDbType.Char).Value = valorvar

Responder a anonymous Cancelar respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *