Foros del Web » Programando para Internet » ASP Clásico »

Problemas con Objeto Command y Parámetros

Estas en el tema de Problemas con Objeto Command y Parámetros en el foro de ASP Clásico en Foros del Web. Hola a todos! Estoy en un conflicto bastante engorroso. Resulta que para el update a una tabla utilizo un objeto de comando, y como la ...
  #1 (permalink)  
Antiguo 28/10/2004, 07:51
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Problemas con Objeto Command y Parámetros

Hola a todos!
Estoy en un conflicto bastante engorroso. Resulta que para el update a una tabla utilizo un objeto de comando, y como la tabla no es muy requerida y la mayoría de los datos puede no ingresarse (de hecho lel 90% de las veces no se ingresarán todos los campos de la tabla), entonces no puedo colocar simplemente las variables que recibo por post porque vienen muchas vacías, por esto mi opción fué el objeto de comando definido mas o menos de esta forma:
set cmUpClient = Server.CreateObject("ADODB.Command")
cmUpClient.ActiveConnection = MM_INFO_SQL_STRING
cmUpClient.CommandText="UPDATE CLIENTES SET COLUMNA="&VARIABLE&" WHERE (IDCLIENTE="&clien&")"
cmInsClient.CommandType = 1
cmInsClient.Prepared = true
cmInsClient.Execute
Pero de esta forma cuando llega una variable vacia, da error.

Entonces buscando en diferentes sitios llequé a w3school y traté de implementar esta solución:
cmUpdClient.CommandText=" UPDATE CLIENTES SET VARIABLE=? WHERE (IDCLIENTE="&clien&") "
Entonces tenía que colocar el valor de la variable de la siguiente forma:
CmUpItem.Parameters.Append CmUpItem.CreateParameter("VARIABLE", 4,1,100)
Con lo que también recibía errores al llevar variables vacías.

Lo que tengo ahora es lo siguiente:
set cmUpdClient = Server.CreateObject("ADODB.Command")
set objParm = Server.CreateObject ( "ADODB.Parameter" )

cmUpdClient.ActiveConnection = MM_INFO_SQL_STRING
cmUpdClient.CommandText=" UPDATE CLIENTES SET VARIABLE=?, WHERE (IDCLIENTE="&clien&") "
cmUpdClient.CommandType = 1
cmUpdClient.Prepared = true

' ------------------------- PARAMETROS PARA UPDATE ------------------
Set objParam =cmUpdClient.CreateParameter("PARAMETRO",200,1,100 , VARIABLE)
objParam.Attributes = 64 Que indica un campo "nulable"(que puede ser nulo)
cmUpdClient.Parameters.Append objParam
PARAMETRO Es el nombre del comando
VARIABLE es la variable que llegaba de la pag anterior.
¿Cuál es el error?????
Gracias de antemano!!!
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #2 (permalink)  
Antiguo 28/10/2004, 08:07
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
mmm, sorry pero mi no entender del todo.

¿Quieres formar una sentencia SQL (Update en este caso) dónde hasta los nombres de columna sean parámetros?
  #3 (permalink)  
Antiguo 28/10/2004, 08:16
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Hola Makire!
Noooo! Definitivamente no, eso ya superaría el limite de mi osadía...jaja!!
Los valores van por parámetro.
Lo que me marea es que tengo estas tres formas de hacerlo y todas, cuando hay un campo que no fue llenado en las modificaciones tiran este error o similar:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]La instrucción preparada '(@P1 varchar(100),@P2 varchar(100),@P3 varchar(100),@P4 real,@P5' espera el parámetro @P3, que no se ha especificado.

/sistema/procesadores/update_cli.asp, line 99
Ahora se comprende mejor?
Gracias por tu atención
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #4 (permalink)  
Antiguo 28/10/2004, 08:35
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
Bueno, yo he usado instrucciones como la de abajo:

Código:
sNoReq=Request("hidsNoReq")
sNo_Prov=Request("hidNoProv")
sObserva=Request("hidObserva")
	
Set adoConn = Server.CreateObject("adodb.connection")
sConn = "Driver={SQL Server};SERVER=10.1.1.1; DATABASE=DB;UID=Iser;PWD=Paswd"
adoConn.IsolationLevel=256 
adoConn.Open  sConn	
adoConn.BeginTrans

dim cmd
set cmd=server.CreateObject("ADODB.command")
Set cmd.ActiveConnection = adoConn

 cmd.CommandText = "INSERT INTO Cotizacion(No_Req, Id_Prov, Fecha, Observacion, EstatusI) 	VALUES(@No_Req,	@Id_Prov,	GETDATE(),	@Observa,	'A')"
cmd.CommandType=adCmdText

IF LEN(sObserva) > 1000 THEN sObserva = MID(sObserva,1,1000)

cmd.Parameters.Append (cmd.CreateParameter("No_Req", adChar, adParamInput, 8, sNoReq))
cmd.Parameters.Append (cmd.CreateParameter("Id_Prov", adChar, adParamInput, 8, sNo_Prov))
cmd.Parameters.Append (cmd.CreateParameter("Observa", adVarChar, adParamInput, 1000, sObserva))
		
cmd.Execute

IF (adoConn.Errors.Count > 0) Then
   adoConn.RollBackTrans
Else	
   adoConn.CommitTrans
End If
Y como puedes ver, para el parámetro "@Observa" (que es el que puede o no puede llegar con información) no hago ninguna validación extra (salvo la longitud) y no hay problemas. Pero se me ocurre que te crees alguna función como esta, por ejemplo:

...
cmd.Parameters.Append (cmd.CreateParameter("Observa", adVarChar, adParamInput, 1000, ValidaDato(sObserva)))
...

Cita:
Function ValidaDato(valor)
if IsNull(Valor) Then
ValidaDato = " "
Else
ValidaDato = valor
End If
End Function
Es muy simple la solución, pero en muchas ocaciones, por estar buscando soluciones complejas no vemos lo más sencillo.

  #5 (permalink)  
Antiguo 28/10/2004, 09:18
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Gracias Myakire!!!
Lo único que creo es que me generaría inconvenientes en las consultas a la tabla, ya que debería preguntar en vez de por el valor null, por espacio con la funcion???
ota consulta además, en caso que no use la función. He visto que muchas veces colocan los valores AdChar o AdVarChar en vez del número de código que le corresponde. Eso es válido o solo para que uno se de cuenta????
Mil disculpas si estoy demasiado preguntona, es que recien comienzo con el tema de los parámetros. Generalmente lo hice con la forma del primer ejemplo que te di.
Sé que hay que progresar pero... solo hace dos semanas que empecé a "Manejar parametros" de este tipo.
Muchas gracias por tu ayuda!!!!
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #6 (permalink)  
Antiguo 28/10/2004, 09:32
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Hay otro punto.
En el ejemplo que me diste quedó algo asi:
cmd.CommandText = "INSERT INTO Cotizacion(No_Req, Id_Prov, Fecha, Observacion, EstatusI) VALUES(@No_Req, @Id_Prov, GETDATE(), @Observa, 'A ')"
Lo que me llama la atención es el tema del arroba.
Va así??? porque yo no lo tengo asi, solo sale así cuando sale el error en el browser...
me estoy mareando mucho!!! Excusess...
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #7 (permalink)  
Antiguo 28/10/2004, 09:43
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
Bueno, si tu campo permite nulos no te debería de marcar error, aún sin validación y con ello te evitas el inconveniente de las consultas (que puede dejar de ser inconveniente usando instrucciones como TRIM, pero bueno), la validación es únicamente para campos NOT NULL que puede ser que el usuario no te envíe (como una fecha, por ejemplo).

Lo de las constantes en lugar de claves numéricas. Para ello solo debes descargar un archivo del internet (del sitio de MS, por ejemplo), llamado adovbs.inc, e incluirlo con un <!-- #INCLUDE File="adovbs.inc" --> al inicio de tus páginas, si lo revisas con detalle, verás que define todas las constantes que se ocupan en operaciones con ADO. Solo es cosa de buscar el número que usualmente ocupas y lo sustituyes por su constante (pe. adVarChar en lugar de 200).

Por lo de las arrobas, bueno, es una costumbre que trabajar con T-SQL en MSSQL-Server. Ahí las arrobas son necesarias para declarar parámetros. Y aparentemente es un estandar que ADO soporta sin problemas. La verdad, es que normalmente uso los parámetros casí únicamente para trabajar con SP, pero como ves, CommandText también los soporta.

Saludos
  #8 (permalink)  
Antiguo 28/10/2004, 09:47
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Ok!
Lo estoy probando y te aviso a ver que sale!
Muchisimas gracias por todo


__________________
Why can't we not be sober?
www.partitorium.com.ar
  #9 (permalink)  
Antiguo 28/10/2004, 09:52
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
, Claro Verinchi, trataré de no confundirte de más

Por cierto, ¿qué son los garrones?

  #10 (permalink)  
Antiguo 28/10/2004, 10:23
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Otra pregunta:
Yo en el update pongo por ejemplo
Update clientes Set NOMBRE=?
CmUpItem.Parameters.Append CmUpItem.CreateParameter("nom", 4,1,100)
y después
CmUpItem("nom") = pnomb
donde
NOMBRE= Columna de la tabla
nom=Nombre del parámetro
pnom=Variable que le llega
Puede ser que para este modelo ponga
Update clientes Set NOMBRE=nom
Tiene alguna estructura particular a seguir o lo puedo poner directamente?
No me está funcionando muy bien el otro ejemplo. De todos modos lo estoy revisando para ver si hay algo que puse mal
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #11 (permalink)  
Antiguo 28/10/2004, 10:42
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
No hay una sintaxis rígida que debas de seguir, como has visto, se pueden crear variables de parámetros y luego asignalar al objeto command, o bien asignar directamente el parámetro. Se igual forma, el CreateParameter, soporta que lo definas con 4 argumentos, o con 5, donde el quinto es el valor inicial del parámetro.

cmd.ActiveConnection = cn
cmd.CommandText = "Update clientes Set clave=?"
cmd.CommandType = adCmdText
cmd.Parameters.Append cmd.CreateParameter("clave", adChar, adParamInput, 5)
'cmd.Parameters.Append cmd.CreateParameter("clave", adChar, adParamInput, 5,"O")
cmd.Parameters("clave") = "O"
Set rs = cmd.Execute
  #12 (permalink)  
Antiguo 28/10/2004, 10:50
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
Inclusive, si tienes más de un parámetro, los puedes llamar por su posición:

cmd.Parameters.Refresh
cmd.Parameters(0).Value = 2
cmd.Parameters(1).Value = 50

Revisa esta liga:
http://www.devguru.com/Technologies/...ollection.html
  #13 (permalink)  
Antiguo 28/10/2004, 11:54
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Ok, Interesante!!!!
Veré de ponerlo en práctica. En cuanto tenga el codigo que funciona te lo muestro, a ver si apruebo... JAJAJAJAJA!!!!
Por otra parte: Los Garrones... en realidad son una parte del cuerpo(pero de la vaca)
Es la parte superior al tobillo, lo que sería la pantorrilla, que generalmente no se cocina por su dureza. Por eso generalmente la expresión: "Es un Garrón" diría: "Es una porquería, o algo muy feo"
En el contexto de mi firma es literalmente... cuando los perros te muerden las pantorrillas
Simple y llanamente
Saludos y prontito estaré comentandote si es que me ha salido el codigo o llorando ante la decepción.
Muchas gracias nuevamente por tu atención
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #14 (permalink)  
Antiguo 28/10/2004, 13:38
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Aquí lo tengo!!!

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252" LCID = 11274 %>
<!--#include file="../Connections/INFO_SQL.asp" -->
<%'------------------------- DEFINICION DE VARIABLES ----------------------------
Dim cam1, cam2, cam3
cam1=cam2=cam3=""
dim cmu

'------------ TOMA DE VALORES DEL FORMULARIO DE INGRESO ----------------------
if (Request.Form("C1")<>"") Then cam1=Request.Form("C1") end if
if (Request.Form("C2")<>"") Then cam2=Request.Form("C2") else cam2=NULL end if
if (Request.Form("C3")<>"") Then cam3=Request.Form("C3") end if
pasaid=Request.Form("pasaid")

'---------------------------------- CONFIGURACION DEL UPDATE ----------------

set cmu = Server.CreateObject("ADODB.Command")

cmu.ActiveConnection = MM_INFO_SQL_STRING
cmu.CommandText=" UPDATE AUXILIO SET campo1=?, campo2=?, campo3=? WHERE (id="&pasaid&") "
cmu.CommandType = 1
cmu.Prepared = true

' ------------------------- PARAMETROS PARA UPDATE ------------------
cmu.Parameters.Append (cmu.CreateParameter("ca1", 200, 1, 100, cam1))
cmu.Parameters.Append (cmu.CreateParameter("ca2", 4, 1, 9, cam2))
cmu.Parameters.Append (cmu.CreateParameter("ca3", 200, 1, 100, cam3))

cmu.Execute


'-------------------------- REDIRECCIONA -------
Response.Redirect("../prueba1.asp")
%>
<head></head>

El punto fue asignarle NULL al que le correspondiera en caso que por post no le llegara nada, de esta forma no lo toma como vacío ni el update/insert, ni la base de datos, que aunque no es requerido el campo, cuando es numérico no deja insertar null
Por que?? Ni idea, pero no me deja borrar cuando ya tiene valor la columna de la tabla, ni cuando lo hago desde el administrador de sql.

Qué te parece????
Lo que si. Aisle el problema para resolverlo. Consejo de un amigo!!!
Saludos a Kaopectate!!!!
Y un abrazo grande para vos Myakire
Muchas gracias por la ayuda que me diste... me sirvió sinceramente de mucho
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #15 (permalink)  
Antiguo 28/10/2004, 14:00
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
Interesante la nueva palabra que acabas de ingresar a mi vocabulario.

Muy organizado y ordenado tu código, así es mucho más fácil darle mantenimiento, te felicito.

No entendí la parte de "pero no me deja borrar cuando ya tiene valor la columna de la tabla, ni cuando lo hago desde el administrador de sql.", no comprendí exactamente a que te refieres.

Saludos
  #16 (permalink)  
Antiguo 29/10/2004, 07:48
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Hola Myakire!!
Me refiero a esto:
Yo genero las tablas desde sql directamente. Muchas veces, para trabajar con datos de prueba, si me es conveniente ingreso los datos directamente desde sql (administrador corporativo).
Lo que observé, es que cuando tengo un campo numérico que permite valores nulos, si voy ingresando (generalmente presionando la tecla tab para cambiar de columna) puedo dejar vacío el campo respectivo. Pero si tengo en uno de los campos de esa columna un dato (cualquiera) y lo que deseo es borrarlo, entonces me tira el error que el valor ingresado no se encuentra dentro de los parámetros establecidos. Luego, creo que es presionando <control> <tab> admite la nulidad de ese campo.
¿Ahora se entiende mejor?
Un abrazo graaaaande
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #17 (permalink)  
Antiguo 29/10/2004, 08:28
Avatar de verinchi  
Fecha de Ingreso: septiembre-2004
Ubicación: Buenos Aires
Mensajes: 647
Antigüedad: 19 años, 8 meses
Puntos: 2
Myakire!
Me ha quedado una duda mas:
Respecto de este código

IF (adoConn.Errors.Count > 0) Then
adoConn.RollBackTrans
Else
adoConn.CommitTrans
End If

Lo que hace es volver a la pagina que generó errores en el envío como estaba, como cuando tira el error el explorer y uno presiona atrás???? o solamente cuida que no se haya insertado basura en los campos de la tabla????
Gracias!!!
__________________
Why can't we not be sober?
www.partitorium.com.ar
  #18 (permalink)  
Antiguo 29/10/2004, 09:19
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
Hola Verinchi.

Por lo de las transacciones. Como sabes, puedes manejar transacciones directamente en la base de datos con el SQLServer, o bien, puedes hacer que el IIS, sea quien envíe todas las actualizaciones en un momento determinado. Las transacciones son muy útiles y es necesario que uno se documente antes para entenderlas bien. Algunas páginas que te pueden servir son:
http://www.devguru.com/Technologies/...egintrans.html
http://www.mcm-sys.com/download/ADO_ASP.pdf
http://msdn.microsoft.com/library/de...connection.asp

El código que mencionas, verifica que no haya habido errores durante alguno de las instrucciones ADO y si fue así, manda todos los cambios a la BD's, de lo contrario, son omitidos. Las tablas quedan como estaban debido a que nunca recibieron instrucciones para ser modificados. Al definir un BeginTrans, nada se envía a la BD hasta no llegar un CommitTrans.

Lo Primero que mencionas, lo de los campos nulos, pues perdona, pero no se me hace lógico. Si tienes una tabla con campos que permiten valores nulos puedes poner o quitar valores son problemas. Si puedes saca una imagen del diseño de la tabla en cuestión y posteala para quitarme de dudas, ya que no se lógico que tengas problemas al eliminar el contenido de un campo que acepta nulos y no es llave secundaria.

Saludos
  #19 (permalink)  
Antiguo 29/10/2004, 10:57
Avatar de Myakire
Colaborador
 
Fecha de Ingreso: enero-2002
Ubicación: Centro de la república
Mensajes: 8.849
Antigüedad: 22 años, 4 meses
Puntos: 146
Cita:
Ok, Aqui vamos con los detalles de la tabla

Tabla:
id | numeric | 5 | valores nulos no
campo1 |char |10| valores nulos si
campo2 | numeric |9 | valores nulos si La que hace el problema
campo3 | char |10| valores nulos si

Definición adicional campo2
Predeterminado nada
Precisión 18
Escala 0
Identidad no
Fórmula nada

Ahora te hago otra pregunta entonces. Sucede que antes de ingresar los datos en una Tabla tengo que validar que no exista.
Sé que tengo que hacerlo mediante consultas, pero el tema es que si rebota el ingreso debería volver a la pag anterior (Hacer un Back) para no perder los datos que estaban llenados y a la vez cambiar el valor de ese campo para que se puedan ingresar los datos.
Hay una forma de lograrlo????
Había pensado que en el caso que en la pag de procesos encuentre el campo repetido redireccione a un sector del body de la misma que notifique el error indicando el rollback.
Qué opinas. Aún no lo pruebo pero... habría forma que un botón en la pag oficie del botón volver del browser????
Mas que nada para que no se pierdan los datos que ya estaban en el formulrario.
Gracias por tu atención!!!
Bueno, eso que mencionas se refiere a manejar el estado. Hay varias formas de hacerlo. Una es como deseas, aunque no sea de lo mejor, simplemente llamando a una función javascript (finalmente deseas ir al Back del navegador, ¿verdad?) como <script>history.back();return false</script>, aunque también podrías volver a llamar a la página e inicializarla con los mismos parámetros que ella envía, pe. <input type=text name=cliente value='<%=request("cliente")%>'>.

Ahora dejame hacer unas pruebitas con una tabla como la que mencionas y te cuento.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 14:13.