Comportamiento EXTRAÑO Trabando con SQL vía CA desde VFP

29/04/2007 - 11:28 por Fabián Tomás de Paula | Informe spam
Espero que con éste código logre hacer ver y puedan interpretar el
problema y de alguna manera solucionar el problema.


Mi VISTA Actualizable se genera bajo los siguientes parámetros

*!*
*!* Lo que sigue, es la información que se desea ingresar dentro
*!* de mi objeto CA, para Armar una vista sobre las tablas ProvxArt y
Provedor
*!* que se encuentran en un SQL Server.
*!*
*!*
*!* La tabla PROVXART y la tabla PROVEDOR.
*!*
*!* PROVXART (Proveedor N(5), IDArticulo VCHAR(12), CodArtpelPrv VCHAR(16))
*!*
*!* El primary Key está compuesto por los campos: Proveedor, IDArticulo
*!*
*!* PROVEDOR.(CodPro N(5), RazonSocia VCHAR(40), ..)
*!*
*!* El primary Key está basado en el campo: CodPro
*!*
*!* Las tablas están relacionadas mediante ésta la siguiente instrucción.
*!*
*!* ALTER TABLE [dbo].[provxart] WITH CHECK ADD CONSTRAINT
*!* [FK_provedor_provxart] FOREIGN KEY([proveedor])
*!* REFERENCES [dbo].[provedor] ([codpro])
*!* ON UPDATE CASCADE
*!* GO
*!* ALTER TABLE [dbo].[provxart] CHECK CONSTRAINT [FK_provedor_provxart]
*!*

PUBLIC _ThisFormIDArt

_ThisFormIDArt = "_1PB20K0MZ5Z"

With This && Objeto Cursor Adapter
STORE .T. TO .AllowDelete, .AllowUpdate, .AllowInsert

.DataSourceType = "ADO"
.DataSource = CREATEOBJECT("ADODB.Recordset")
.UpdateNameList = "Proveedor Provxart.Proveedor, Idarticulo
Provxart.Idarticulo"
.UpdaTableFieldList = "Proveedor, Idarticulo"
.Tables = "ProvxArt"
.KeyfieldList = "Proveedor, Idarticulo"
.SendUpdates = .T.
.MapBinary = .T.
.MapVarchar = .T.
.Alias = "Sql_ProveedoresdeunArticulo"
.BufferModeOverride = 5

.SelectCmd = TEXTMERGE("SELECT Provxart.*, Provedor.RazonSocia FROM
provxart "+;
"LEFT OUTER JOIN provedor ON Provxart.Proveedor = Provedor.codpro
"+;
"GROUP BY ProvxArt.Proveedor, ProvxArt.IDArticulo, "+;
"ProvxArt.CodArtpelPrv, Provedor.RazonSocia "+;
"HAVING ProvxArt.IDArticulo = '<<_ThisFormIDArt>>' "+;
"ORDER BY Provedor.razonsocia")

.CursorFill()
EndWith

Esto me da por resultado un cursor. Que para hacer UPDATES (a) no hay
inconvenientes, tampoco cuando hago INSERTS (b).

Utilizo TABLEUPDATE(.F., .F.) para cualquier modificación, ya sea del caso
(a) o del (b) En el primero, no hay problemas y en el segundo, AERROR() me
devuelve lo
siguiente.

"Microsoft Cursor Engine : Información de columna clave insuficiente para
realizar la operación Update o Refresh"

Ahora bien. Si cambio la instrucción SQL y saco la opción de GRUPO, me borra
el registro de ProvxArt, pero a su vez es como que quiere eliminar al
Proveedor también
y entonces ahí me tira
el siguiente error.

Microsoft OLE DB Provider for SQL Server : Instrucción DELETE en conflicto
con la restricción REFERENCE "FK_provxart_provedor". El conflicto ha
aparecido en la base de datos "HorusFarma", tabla "dbo.provxart", column
'proveedor'.

Tengo que sacar la conclusión de que una VISTA hecha vía CA, con AllowDelete
en .T., haciendo un DELETE y posterior un TABLEUPDATE(), solo borraría el
REGISTRO en cuestión, sin generar error alguno, solo y sí la VISTA no haga
referencia más que a una sola tabla?

Esto es un hecho, ya que si hago:

PUBLIC _ThisFormIDArt

_ThisFormIDArt = "_1PB20K0MZ5Z"

With This && Objeto Cursor Adapter
STORE .T. TO .AllowDelete, .AllowUpdate, .AllowInsert

.DataSourceType = "ADO"
.DataSource = CREATEOBJECT("ADODB.Recordset")
.UpdateNameList = "Proveedor Provxart.Proveedor, Idarticulo
Provxart.Idarticulo"
.UpdaTableFieldList = "Proveedor, Idarticulo"
.Tables = "ProvxArt"
.KeyfieldList = "Proveedor, Idarticulo"
.SendUpdates = .T.
.MapBinary = .T.
.MapVarchar = .T.
.Alias = "Sql_ProveedoresdeunArticulo"
.BufferModeOverride = 5

.SelectCmd = TEXTMERGE("SELECT * FROM provxart "+;
"WHERE ProvxArt.IDArticulo
"+;
"= '<<_ThisFormIDArt>>'
"+;
"ORDER BY
Provedor.razonsocia")

.CursorFill()
EndWith

Cualquier modificación que haga, FUNCIONA sin que AERROR() me devuelva error
alguno. Alguien
me puede dar alguna otra sugerencia de como solucionar ésto? O como dije,
LAS VISTAS que apuntan
a más de una TABLA al efectuar un DELETE siempre va a pasar este error???

Saludos a todos. Fabián.
 

Leer las respuestas

#1 Javier Loria
29/04/2007 - 14:38 | Informe spam
Hola:
Algunas cosas:
1) Se las tablas tienen Llave Foranea estre elllas, la BD te garantiza que
no va a existir en articulo sin proveedor, por lo que no necesitas hacer
"provxart LEFT OUTER JOIN provedor" lo puedes cambiar con un simple JOIN.
2) El GROUP BY es innecesario ya que el codigo de Proveedor es llave
primaria.
3) El objeto Recordset de ADO tiene una propiedad dinamica llamada Unique
Table este metodo es el que quieres fijar para que el ADO solo borre datos
de la tabla ProvxArt y no de la otra.
Por ultimo, ADO es una tecnologia que va de salida, yo no invertiria mas
codigo en ADO. Porque no usas ADO.NET?
Saludos,


Javier Loria
Costa Rica (MVP)
Se aprecia la inclusion de DDL (CREATE, INSERTS, etc.)
que pueda ser copiado y pegado al Query Analizer.
La version de SQL y Service Pack tambien ayuda.

"Fabián Tomás de Paula" wrote in message
news:
Espero que con éste código logre hacer ver y puedan interpretar el
problema y de alguna manera solucionar el problema.


Mi VISTA Actualizable se genera bajo los siguientes parámetros

*!*
*!* Lo que sigue, es la información que se desea ingresar dentro
*!* de mi objeto CA, para Armar una vista sobre las tablas ProvxArt y
Provedor
*!* que se encuentran en un SQL Server.
*!*
*!*
*!* La tabla PROVXART y la tabla PROVEDOR.
*!*
*!* PROVXART (Proveedor N(5), IDArticulo VCHAR(12), CodArtpelPrv
VCHAR(16))
*!*
*!* El primary Key está compuesto por los campos: Proveedor, IDArticulo
*!*
*!* PROVEDOR.(CodPro N(5), RazonSocia VCHAR(40), ..)
*!*
*!* El primary Key está basado en el campo: CodPro
*!*
*!* Las tablas están relacionadas mediante ésta la siguiente instrucción.
*!*
*!* ALTER TABLE [dbo].[provxart] WITH CHECK ADD CONSTRAINT
*!* [FK_provedor_provxart] FOREIGN KEY([proveedor])
*!* REFERENCES [dbo].[provedor] ([codpro])
*!* ON UPDATE CASCADE
*!* GO
*!* ALTER TABLE [dbo].[provxart] CHECK CONSTRAINT [FK_provedor_provxart]
*!*

PUBLIC _ThisFormIDArt

_ThisFormIDArt = "_1PB20K0MZ5Z"

With This && Objeto Cursor Adapter
STORE .T. TO .AllowDelete, .AllowUpdate, .AllowInsert

.DataSourceType = "ADO"
.DataSource = CREATEOBJECT("ADODB.Recordset")
.UpdateNameList = "Proveedor Provxart.Proveedor, Idarticulo
Provxart.Idarticulo"
.UpdaTableFieldList = "Proveedor, Idarticulo"
.Tables = "ProvxArt"
.KeyfieldList = "Proveedor, Idarticulo"
.SendUpdates = .T.
.MapBinary = .T.
.MapVarchar = .T.
.Alias = "Sql_ProveedoresdeunArticulo"
.BufferModeOverride = 5

.SelectCmd = TEXTMERGE("SELECT Provxart.*, Provedor.RazonSocia FROM
provxart "+;
"LEFT OUTER JOIN provedor ON Provxart.Proveedor = Provedor.codpro
"+;
"GROUP BY ProvxArt.Proveedor, ProvxArt.IDArticulo, "+;
"ProvxArt.CodArtpelPrv, Provedor.RazonSocia "+;
"HAVING ProvxArt.IDArticulo = '<<_ThisFormIDArt>>' "+;
"ORDER BY Provedor.razonsocia")

.CursorFill()
EndWith

Esto me da por resultado un cursor. Que para hacer UPDATES (a) no hay
inconvenientes, tampoco cuando hago INSERTS (b).

Utilizo TABLEUPDATE(.F., .F.) para cualquier modificación, ya sea del caso
(a) o del (b) En el primero, no hay problemas y en el segundo, AERROR() me
devuelve lo
siguiente.

"Microsoft Cursor Engine : Información de columna clave insuficiente para
realizar la operación Update o Refresh"

Ahora bien. Si cambio la instrucción SQL y saco la opción de GRUPO, me
borra
el registro de ProvxArt, pero a su vez es como que quiere eliminar al
Proveedor también
y entonces ahí me tira
el siguiente error.

Microsoft OLE DB Provider for SQL Server : Instrucción DELETE en conflicto
con la restricción REFERENCE "FK_provxart_provedor". El conflicto ha
aparecido en la base de datos "HorusFarma", tabla "dbo.provxart", column
'proveedor'.

Tengo que sacar la conclusión de que una VISTA hecha vía CA, con
AllowDelete
en .T., haciendo un DELETE y posterior un TABLEUPDATE(), solo borraría el
REGISTRO en cuestión, sin generar error alguno, solo y sí la VISTA no haga
referencia más que a una sola tabla?

Esto es un hecho, ya que si hago:

PUBLIC _ThisFormIDArt

_ThisFormIDArt = "_1PB20K0MZ5Z"

With This && Objeto Cursor Adapter
STORE .T. TO .AllowDelete, .AllowUpdate, .AllowInsert

.DataSourceType = "ADO"
.DataSource = CREATEOBJECT("ADODB.Recordset")
.UpdateNameList = "Proveedor Provxart.Proveedor, Idarticulo
Provxart.Idarticulo"
.UpdaTableFieldList = "Proveedor, Idarticulo"
.Tables = "ProvxArt"
.KeyfieldList = "Proveedor, Idarticulo"
.SendUpdates = .T.
.MapBinary = .T.
.MapVarchar = .T.
.Alias = "Sql_ProveedoresdeunArticulo"
.BufferModeOverride = 5

.SelectCmd = TEXTMERGE("SELECT * FROM provxart "+;
"WHERE
ProvxArt.IDArticulo
"+;
"= '<<_ThisFormIDArt>>'
"+;
"ORDER BY
Provedor.razonsocia")

.CursorFill()
EndWith

Cualquier modificación que haga, FUNCIONA sin que AERROR() me devuelva
error
alguno. Alguien
me puede dar alguna otra sugerencia de como solucionar ésto? O como dije,
LAS VISTAS que apuntan
a más de una TABLA al efectuar un DELETE siempre va a pasar este error???

Saludos a todos. Fabián.

Preguntas similares