[GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

2011-05-24 Por tema Rafael Copquin
Ahora yo tengo una pregunta sobre SQL Server: es el manejo de 
transacciones, que es diferente de la forma en que VFP las maneja.


Veamos el ejemplo clásico de una factura. Dos tablas, una cabecera y 
otra de detalle.


Yo genero dos cursor adapters vacíos con este código

local cCmd

cCmd = [select * from cabecera where 1=0]
y genero el CA 'curCabecera'  tengo una clase que genera CA , pero es 
un código largo que no viene al caso


cCmd = [select * from detalles where 1=0]
y genero el CA 'curDetalles'

Para hacerla corta, al grabar hago algo así

cCmd = [begin transaction]
sqlexec(nHandle,cCmd)  con lo que le mando al SQL la orden de iniciar 
la transacción

Luego

insert into curCabecera 
   lOK = tableupdate(.t.,.t.,'curCabecera')
   if lOK
  select curFactura  este es un cursor local que opera con una grilla
  scan all
scatter name oFac
insert into curDetalles from name oFac
  endscan
  lOK = tableupdate(.t.,.t.,'curDetalles')
   if lOK
 cCmd = 'IF @@TRANCOUNT  0 COMMIT'
   else
cCmd = 'IF @@TRANCOUNT  0 ROLLBACK'
  endif
   sqlexec(nHandle,cCmd)

Pero sé que a esto le falta una pata, porque si provoco un error a 
propósito en la grabación, para que la segunda tabla no se grabe, por 
ejemplo), la segunda tabla no se graba pero la primera se graba igual.


Intenté usar transacciones manuales antes del begin transaction
#DEFINE DB_TRANSMANUAL  2
SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSMANUAL)

y luego volverlas automáticas después del end transaction
#DEFINE DB_TRANSAUTO1
SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSAUTO)

Pero esto hace que los cursor adapters no graben nada

Me gustaría ver qué mecanismo usan Uds para manejar esto. A lo mejor el 
hecho de que estoy usando cursor adapters cambia las cosas respecto de 
hacer comandos que graben directamente en las tablas del SQL Server. 
Después de todo, un CA es como una vista de VFP, con propiedades y 
métodos propios, pero vista al fin.


Pero como Pancho parece que la tiene clara, la pregunta es para vos (o 
cualquier otro que también la tenga clara)


Rafael Copquin





[GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

2011-05-24 Por tema francisco prieto
Rafa,

No es que la tenga tan clara sino que me crucé con tantos quilombos en
implementaciones que decidí no utilizar cursoradapters, sino una clase
propia a la que la llame rstocursor... pero eso es harina de otro costal y
si queres en otro momento la vemos.

Utilizo, gracias a esta clase ADODB y para trabajar con transacciones
simplemente hago esto:

oConexionActual.Execute(SET IMPLICIT_TRANSACTIONS OFF)

oConexionActual.Execute(BEGIN TRANSACTION)

Luego por ejemplo hago un insert en el  motor de la siguiente forma

lcSql=Insert Into ColaEspera
(Orden_cEsp,F_Llegada,Nro_Turno,Estado,Flg_Espera,IdActuante,IdDerivad)
VALUES (+;
 '+cOrden.Nro_Turno+',+;
'+lcLlegada+',+;
 '+cOrden.Nro_Turno+',+;
'ES',+;
 'P',+;
NULL+,+;
'+cOrden.IdDerivador+')
 Try
oConexionActual.Execute(lcSql)
Catch To loError
 llHuboError=.T.
lcTexto=La instruccion +Chr(13)+Chr(10)+;
 lcSql+Chr(13)+Chr(10)+;
emitio el error +Alltrim(Str(loError.ErrorNo))+ - +loError.Message
 Strtofile(Transform(Date(),@E)+ +Ttoc(Datetime(),2)+
+_Screen.UsrName+ (+;
ALLTRIM(_Screen.AppName)+)
+lcTexto,_Screen.DirApp+_Screen.MisErrores.ArchLog,1)
 Endtry


y finalmente, cuando termino con todo...

If llHuboError
oConexionActual.Execute(ROLLBACK TRANSACTION)
 Messagebox(Se produjo un error interno durante la grabación.,16,Avise a
Sistemas)
Else
oConexionActual.Execute(COMMIT TRANSACTION)
Endif

Esta operatoria nunca me causo los errores que vos mencionas

Tengo otros quilombos (quien no? :)), pero hasta el momento con SqlServer
fueron todas sonrisas...

Saludos,

Pancho
Cordoba
El 24 de mayo de 2011 08:24, Rafael Copquin rcopq...@ciudad.com.arescribió:

 Ahora yo tengo una pregunta sobre SQL Server: es el manejo de
 transacciones, que es diferente de la forma en que VFP las maneja.

 Veamos el ejemplo clásico de una factura. Dos tablas, una cabecera y otra
 de detalle.

 Yo genero dos cursor adapters vacíos con este código

 local cCmd

 cCmd = [select * from cabecera where 1=0]
 y genero el CA 'curCabecera'  tengo una clase que genera CA , pero es un
 código largo que no viene al caso

 cCmd = [select * from detalles where 1=0]
 y genero el CA 'curDetalles'

 Para hacerla corta, al grabar hago algo así

 cCmd = [begin transaction]
 sqlexec(nHandle,cCmd)  con lo que le mando al SQL la orden de iniciar la
 transacción
 Luego

insert into curCabecera 
   lOK = tableupdate(.t.,.t.,'curCabecera')
   if lOK
  select curFactura  este es un cursor local que opera con una grilla
  scan all
scatter name oFac
insert into curDetalles from name oFac
  endscan
  lOK = tableupdate(.t.,.t.,'curDetalles')
   if lOK
 cCmd = 'IF @@TRANCOUNT  0 COMMIT'
   else
cCmd = 'IF @@TRANCOUNT  0 ROLLBACK'
  endif
   sqlexec(nHandle,cCmd)

 Pero sé que a esto le falta una pata, porque si provoco un error a
 propósito en la grabación, para que la segunda tabla no se grabe, por
 ejemplo), la segunda tabla no se graba pero la primera se graba igual.

 Intenté usar transacciones manuales antes del begin transaction
 #DEFINE DB_TRANSMANUAL  2
 SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSMANUAL)

 y luego volverlas automáticas después del end transaction
 #DEFINE DB_TRANSAUTO1
 SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSAUTO)

 Pero esto hace que los cursor adapters no graben nada

 Me gustaría ver qué mecanismo usan Uds para manejar esto. A lo mejor el
 hecho de que estoy usando cursor adapters cambia las cosas respecto de hacer
 comandos que graben directamente en las tablas del SQL Server. Después de
 todo, un CA es como una vista de VFP, con propiedades y métodos propios,
 pero vista al fin.

 Pero como Pancho parece que la tiene clara, la pregunta es para vos (o
 cualquier otro que también la tenga clara)

 Rafael Copquin






[GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

2011-05-24 Por tema Omar Bellio
Rafa, lo que te debe estar pasando es que la conexión que usás para los
CursorAdapters es distinta a la que usa el SqlExec, por lo tanto, las
transacciones y las otras instrucciones “no están viendo el mismo canal”,
por así decirlo.

 

La solución de Pancho, como podrás ver, usa la misma conexión ADO para toda
la operatoria entonces no tiene dramas.

 

Otra observación, me parece que si cambiás tu bloque de instrucciones Scan
Alll… EndScan por una sola instrucción Insert into… Select… from… vas a
tener mejor rendimiento (aunque los registros sean poquitos, me parece más
elegante, pero esto es sólo una cuestión de gustos)

 

Salute!

 

De: GUFA@mug.org.ar [mailto:GUFA@mug.org.ar] En nombre de francisco prieto
Enviado el: martes, 24 de mayo de 2011 08:38 a.m.
Para: GUFA List Member
Asunto: [GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

 

Rafa,

 

No es que la tenga tan clara sino que me crucé con tantos quilombos en
implementaciones que decidí no utilizar cursoradapters, sino una clase
propia a la que la llame rstocursor... pero eso es harina de otro costal y
si queres en otro momento la vemos.

 

Utilizo, gracias a esta clase ADODB y para trabajar con transacciones
simplemente hago esto:

 

oConexionActual.Execute(SET IMPLICIT_TRANSACTIONS OFF)

 

oConexionActual.Execute(BEGIN TRANSACTION)

 

Luego por ejemplo hago un insert en el  motor de la siguiente forma

 

   lcSql=Insert Into ColaEspera
(Orden_cEsp,F_Llegada,Nro_Turno,Estado,Flg_Espera,IdActuante,IdDerivad)
VALUES (+;

   '+cOrden.Nro_Turno+',+;

   '+lcLlegada+',+;

   '+cOrden.Nro_Turno+',+;

   'ES',+;

   'P',+;

   NULL+,+;

   '+cOrden.IdDerivador+')

   Try

 
oConexionActual.Execute(lcSql)

   Catch To loError

   llHuboError=.T.

   lcTexto=La instruccion
+Chr(13)+Chr(10)+;

 
lcSql+Chr(13)+Chr(10)+;

   emitio el error
+Alltrim(Str(loError.ErrorNo))+ - +loError.Message

 
Strtofile(Transform(Date(),@E)+ +Ttoc(Datetime(),2)+
+_Screen.UsrName+ (+;

 
ALLTRIM(_Screen.AppName)+)
+lcTexto,_Screen.DirApp+_Screen.MisErrores.ArchLog,1)

   Endtry

 

 

y finalmente, cuando termino con todo...

 

If llHuboError

oConexionActual.Execute(ROLLBACK TRANSACTION)

Messagebox(Se produjo un error interno durante la
grabación.,16,Avise a Sistemas)

Else

oConexionActual.Execute(COMMIT TRANSACTION)

Endif

 

Esta operatoria nunca me causo los errores que vos mencionas

 

Tengo otros quilombos (quien no? :)), pero hasta el momento con SqlServer
fueron todas sonrisas...

 

Saludos,

 

Pancho

Cordoba

El 24 de mayo de 2011 08:24, Rafael Copquin rcopq...@ciudad.com.ar
escribió:

Ahora yo tengo una pregunta sobre SQL Server: es el manejo de transacciones,
que es diferente de la forma en que VFP las maneja.

Veamos el ejemplo clásico de una factura. Dos tablas, una cabecera y otra de
detalle.

Yo genero dos cursor adapters vacíos con este código

local cCmd

cCmd = [select * from cabecera where 1=0]
y genero el CA 'curCabecera'  tengo una clase que genera CA , pero es un
código largo que no viene al caso

cCmd = [select * from detalles where 1=0]
y genero el CA 'curDetalles'

Para hacerla corta, al grabar hago algo así

cCmd = [begin transaction]
sqlexec(nHandle,cCmd)  con lo que le mando al SQL la orden de iniciar la
transacción
Luego

   insert into curCabecera 
  lOK = tableupdate(.t.,.t.,'curCabecera')
  if lOK
 select curFactura  este es un cursor local que opera con una grilla
 scan all
   scatter name oFac
   insert into curDetalles from name oFac
 endscan
 lOK = tableupdate(.t.,.t.,'curDetalles')
  if lOK
cCmd = 'IF @@TRANCOUNT  0 COMMIT'
  else
   cCmd = 'IF @@TRANCOUNT  0 ROLLBACK'
 endif
  sqlexec(nHandle,cCmd)

Pero sé que a esto le falta una pata, porque si provoco un error a propósito
en la grabación, para que la segunda tabla no se grabe, por ejemplo), la
segunda tabla no se graba pero la primera se graba igual.

Intenté usar transacciones manuales antes del begin transaction
#DEFINE DB_TRANSMANUAL  2
SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSMANUAL)

y luego volverlas automáticas después del end transaction
#DEFINE DB_TRANSAUTO1
SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSAUTO)

Pero esto hace que los cursor adapters no graben nada

Me gustaría ver qué mecanismo usan Uds para manejar esto. A lo mejor el
hecho de que estoy usando cursor adapters cambia las cosas

[GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

2011-05-24 Por tema Rafael Copquin
La conexión es la misma. No se cambia durante la transacción. Y por 
ahora estoy usando ODBC, no ADO.


Lei por ahi que al mandar el comando begin transaction via sqlexec

sqlexec(nHandle,'BEGIN TRANSACTION')

el ODBC pone automáticamente en MANUAL  la transacción ( le manda el 
valor 1 ) ¿es asi?


Rafael Copquin


El 24/05/2011 9:28, Omar Bellio escribió:


Rafa, lo que te debe estar pasando es que la conexión que usás para 
los CursorAdapters es distinta a la que usa el SqlExec, por lo tanto, 
las transacciones y las otras instrucciones no están viendo el mismo 
canal, por así decirlo.


La solución de Pancho, como podrás ver, usa la misma conexión ADO para 
toda la operatoria entonces no tiene dramas.


Otra observación, me parece que si cambiás tu bloque de instrucciones 
Scan Alll... EndScan por una sola instrucción Insert into... Select... 
from... vas a tener mejor rendimiento (aunque los registros sean 
poquitos, me parece más elegante, pero esto es sólo una cuestión de 
gustos)


Salute!

*De:*GUFA@mug.org.ar [mailto:GUFA@mug.org.ar] *En nombre de *francisco 
prieto

*Enviado el:* martes, 24 de mayo de 2011 08:38 a.m.
*Para:* GUFA List Member
*Asunto:* [GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

Rafa,

No es que la tenga tan clara sino que me crucé con tantos quilombos en 
implementaciones que decidí no utilizar cursoradapters, sino una clase 
propia a la que la llame rstocursor... pero eso es harina de otro 
costal y si queres en otro momento la vemos.


Utilizo, gracias a esta clase ADODB y para trabajar con transacciones 
simplemente hago esto:


oConexionActual.Execute(SET IMPLICIT_TRANSACTIONS OFF)

oConexionActual.Execute(BEGIN TRANSACTION)

Luego por ejemplo hago un insert en el  motor de la siguiente forma

lcSql=Insert Into ColaEspera 
(Orden_cEsp,F_Llegada,Nro_Turno,Estado,Flg_Espera,IdActuante,IdDerivad) VALUES 
(+;


'+cOrden.Nro_Turno+',+;

'+lcLlegada+',+;

'+cOrden.Nro_Turno+',+;

'ES',+;

'P',+;

NULL+,+;

'+cOrden.IdDerivador+')

Try

oConexionActual.Execute(lcSql)

Catch To loError

llHuboError=.T.

lcTexto=La instruccion +Chr(13)+Chr(10)+;

lcSql+Chr(13)+Chr(10)+;

emitio el error +Alltrim(Str(loError.ErrorNo))+ - +loError.Message

Strtofile(Transform(Date(),@E)+ +Ttoc(Datetime(),2)+ 
+_Screen.UsrName+ (+;


ALLTRIM(_Screen.AppName)+) 
+lcTexto,_Screen.DirApp+_Screen.MisErrores.ArchLog,1)


Endtry

y finalmente, cuando termino con todo...

If llHuboError

oConexionActual.Execute(ROLLBACK TRANSACTION)

Messagebox(Se produjo un error interno durante la 
grabación.,16,Avise a Sistemas)


Else

oConexionActual.Execute(COMMIT TRANSACTION)

Endif

Esta operatoria nunca me causo los errores que vos mencionas

Tengo otros quilombos (quien no? :)), pero hasta el momento con 
SqlServer fueron todas sonrisas...


Saludos,

Pancho

Cordoba

El 24 de mayo de 2011 08:24, Rafael Copquin rcopq...@ciudad.com.ar 
mailto:rcopq...@ciudad.com.ar escribió:


Ahora yo tengo una pregunta sobre SQL Server: es el manejo de 
transacciones, que es diferente de la forma en que VFP las maneja.


Veamos el ejemplo clásico de una factura. Dos tablas, una cabecera y 
otra de detalle.


Yo genero dos cursor adapters vacíos con este código

local cCmd

cCmd = [select * from cabecera where 1=0]
y genero el CA 'curCabecera'  tengo una clase que genera CA , pero 
es un código largo que no viene al caso


cCmd = [select * from detalles where 1=0]
y genero el CA 'curDetalles'

Para hacerla corta, al grabar hago algo así

cCmd = [begin transaction]
sqlexec(nHandle,cCmd)  con lo que le mando al SQL la orden de 
iniciar la transacción

Luego

   insert into curCabecera 
  lOK = tableupdate(.t.,.t.,'curCabecera')
  if lOK
 select curFactura  este es un cursor local que opera con una grilla
 scan all
   scatter name oFac
   insert into curDetalles from name oFac
 endscan
 lOK = tableupdate(.t.,.t.,'curDetalles')
  if lOK
cCmd = 'IF @@TRANCOUNT  0 COMMIT'
  else
   cCmd = 'IF @@TRANCOUNT  0 ROLLBACK'
 endif
  sqlexec(nHandle,cCmd)

Pero sé que a esto le falta una pata, porque si provoco un error a 
propósito en la grabación, para que la segunda tabla no se grabe, por 
ejemplo), la segunda tabla no se graba pero la primera se graba igual.


Intenté usar transacciones manuales antes del begin transaction
#DEFINE DB_TRANSMANUAL  2
SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSMANUAL)

y luego volverlas automáticas después del end transaction
#DEFINE DB_TRANSAUTO1
SQLSetProp(nHandle, TRANSACTIONS, DB_TRANSAUTO)

Pero esto hace que los cursor adapters no graben nada

Me gustaría ver qué mecanismo usan Uds para manejar esto. A lo mejor 
el hecho de que estoy usando cursor adapters cambia las cosas respecto 
de hacer comandos que graben directamente en las tablas del SQL 
Server. Después de todo, un CA es como una vista de VFP, con 
propiedades y métodos propios, pero vista al fin.


Pero como Pancho parece que la tiene clara, la pregunta es para vos (o 
cualquier otro

[GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

2011-05-24 Por tema francisco prieto
Rafa,

Me parece que el temita esta por este link...

http://msdn.microsoft.com/en-us/library/ms131281(v=SQL.100).aspx

http://msdn.microsoft.com/en-us/library/ms131281(v=SQL.100).aspxSaludos,

Pancho
Cordoba

El 24 de mayo de 2011 12:26, Rafael Copquin rcopq...@ciudad.com.arescribió:

  La conexión es la misma. No se cambia durante la transacción. Y por ahora
 estoy usando ODBC, no ADO.

 Lei por ahi que al mandar el comando begin transaction via sqlexec

 sqlexec(nHandle,'BEGIN TRANSACTION')

 el ODBC pone automáticamente en MANUAL  la transacción ( le manda el valor
 1 ) ¿es asi?

 Rafael Copquin


 El 24/05/2011 9:28, Omar Bellio escribió:

  Rafa, lo que te debe estar pasando es que la conexión que usás para los
 CursorAdapters es distinta a la que usa el SqlExec, por lo tanto, las
 transacciones y las otras instrucciones “no están viendo el mismo canal”,
 por así decirlo.



 La solución de Pancho, como podrás ver, usa la misma conexión ADO para toda
 la operatoria entonces no tiene dramas.



 Otra observación, me parece que si cambiás tu bloque de instrucciones Scan
 Alll… EndScan por una sola instrucción Insert into… Select… from… vas a
 tener mejor rendimiento (aunque los registros sean poquitos, me parece más
 elegante, pero esto es sólo una cuestión de gustos)



 Salute!



 *De:* GUFA@mug.org.ar [mailto:GUFA@mug.org.ar GUFA@mug.org.ar] *En
 nombre de *francisco prieto
 *Enviado el:* martes, 24 de mayo de 2011 08:38 a.m.
 *Para:* GUFA List Member
 *Asunto:* [GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones



 Rafa,



 No es que la tenga tan clara sino que me crucé con tantos quilombos en
 implementaciones que decidí no utilizar cursoradapters, sino una clase
 propia a la que la llame rstocursor... pero eso es harina de otro costal y
 si queres en otro momento la vemos.



 Utilizo, gracias a esta clase ADODB y para trabajar con transacciones
 simplemente hago esto:



 oConexionActual.Execute(SET IMPLICIT_TRANSACTIONS OFF)



 oConexionActual.Execute(BEGIN TRANSACTION)



 Luego por ejemplo hago un insert en el  motor de la siguiente forma



lcSql=Insert Into ColaEspera
 (Orden_cEsp,F_Llegada,Nro_Turno,Estado,Flg_Espera,IdActuante,IdDerivad)
 VALUES (+;

'+cOrden.Nro_Turno+',+;

'+lcLlegada+',+;

'+cOrden.Nro_Turno+',+;

'ES',+;

'P',+;

NULL+,+;

'+cOrden.IdDerivador+')

Try


 oConexionActual.Execute(lcSql)

Catch To loError

llHuboError=.T.

lcTexto=La instruccion
 +Chr(13)+Chr(10)+;


 lcSql+Chr(13)+Chr(10)+;

emitio el
 error +Alltrim(Str(loError.ErrorNo))+ - +loError.Message


 Strtofile(Transform(Date(),@E)+
 +Ttoc(Datetime(),2)+ +_Screen.UsrName+ (+;


 ALLTRIM(_Screen.AppName)+)
 +lcTexto,_Screen.DirApp+_Screen.MisErrores.ArchLog,1)

Endtry





 y finalmente, cuando termino con todo...



 If llHuboError

 oConexionActual.Execute(ROLLBACK TRANSACTION)

 Messagebox(Se produjo un error interno durante la
 grabación.,16,Avise a Sistemas)

 Else

 oConexionActual.Execute(COMMIT TRANSACTION)

 Endif



 Esta operatoria nunca me causo los errores que vos mencionas



 Tengo otros quilombos (quien no? :)), pero hasta el momento con SqlServer
 fueron todas sonrisas...



 Saludos,



 Pancho

 Cordoba

 El 24 de mayo de 2011 08:24, Rafael Copquin rcopq...@ciudad.com.ar
 escribió:

 Ahora yo tengo una pregunta sobre SQL Server: es el manejo de
 transacciones, que es diferente de la forma en que VFP las maneja.


 Veamos el ejemplo clásico de una factura. Dos tablas, una cabecera y otra
 de detalle.

 Yo genero dos cursor adapters vacíos con este código

 local cCmd

 cCmd = [select * from cabecera where 1=0]
 y genero el CA 'curCabecera'  tengo una clase que genera CA , pero es un
 código largo que no viene al caso

 cCmd = [select * from detalles where 1=0]
 y genero el CA 'curDetalles'

 Para hacerla corta, al grabar hago algo así

 cCmd = [begin transaction]
 sqlexec(nHandle,cCmd)  con lo que le mando al SQL la orden de iniciar la
 transacción
 Luego

insert into curCabecera 
   lOK = tableupdate(.t.,.t.,'curCabecera')
   if lOK
  select curFactura  este es un cursor local que opera con una grilla
  scan all
scatter name oFac
insert into curDetalles from name oFac

[GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

2011-05-24 Por tema Rafael Copquin
Ya lo lei, pero sigue la confusión. Voy a experimentar y seguro que por 
prueba y error lo saco. (mis famosas HCS :-) )



El 24/05/2011 12:44, francisco prieto escribió:

Rafa,

Me parece que el temita esta por este link...

http://msdn.microsoft.com/en-us/library/ms131281(v=SQL.100).aspx 
http://msdn.microsoft.com/en-us/library/ms131281%28v=SQL.100%29.aspx


Saludos,

Pancho
Cordoba

El 24 de mayo de 2011 12:26, Rafael Copquin rcopq...@ciudad.com.ar 
mailto:rcopq...@ciudad.com.ar escribió:


La conexión es la misma. No se cambia durante la transacción. Y
por ahora estoy usando ODBC, no ADO.

Lei por ahi que al mandar el comando begin transaction via sqlexec

sqlexec(nHandle,'BEGIN TRANSACTION')

el ODBC pone automáticamente en MANUAL  la transacción ( le manda
el valor 1 ) ¿es asi?

Rafael Copquin


El 24/05/2011 9:28, Omar Bellio escribió:


Rafa, lo que te debe estar pasando es que la conexión que usás
para los CursorAdapters es distinta a la que usa el SqlExec, por
lo tanto, las transacciones y las otras instrucciones “no están
viendo el mismo canal”, por así decirlo.

La solución de Pancho, como podrás ver, usa la misma conexión ADO
para toda la operatoria entonces no tiene dramas.

Otra observación, me parece que si cambiás tu bloque de
instrucciones Scan Alll… EndScan por una sola instrucción Insert
into… Select… from… vas a tener mejor rendimiento (aunque los
registros sean poquitos, me parece más elegante, pero esto es
sólo una cuestión de gustos)

Salute!

*De:*GUFA@mug.org.ar mailto:GUFA@mug.org.ar
[mailto:GUFA@mug.org.ar] *En nombre de *francisco prieto
*Enviado el:* martes, 24 de mayo de 2011 08:38 a.m.
*Para:* GUFA List Member
*Asunto:* [GUFA] OFF TOPIC TRANSACT SQL - manejo de transacciones

Rafa,

No es que la tenga tan clara sino que me crucé con tantos
quilombos en implementaciones que decidí no utilizar
cursoradapters, sino una clase propia a la que la llame
rstocursor... pero eso es harina de otro costal y si queres en
otro momento la vemos.

Utilizo, gracias a esta clase ADODB y para trabajar con
transacciones simplemente hago esto:

oConexionActual.Execute(SET IMPLICIT_TRANSACTIONS OFF)

oConexionActual.Execute(BEGIN TRANSACTION)

Luego por ejemplo hago un insert en el  motor de la siguiente forma

lcSql=Insert Into ColaEspera
(Orden_cEsp,F_Llegada,Nro_Turno,Estado,Flg_Espera,IdActuante,IdDerivad)
VALUES (+;

'+cOrden.Nro_Turno+',+;

'+lcLlegada+',+;

'+cOrden.Nro_Turno+',+;

'ES',+;

'P',+;

NULL+,+;

'+cOrden.IdDerivador+')

Try

oConexionActual.Execute(lcSql)

Catch To loError

llHuboError=.T.

lcTexto=La instruccion +Chr(13)+Chr(10)+;

lcSql+Chr(13)+Chr(10)+;

emitio el error +Alltrim(Str(loError.ErrorNo))+ -
+loError.Message

Strtofile(Transform(Date(),@E)+ +Ttoc(Datetime(),2)+
+_Screen.UsrName+ (+;

ALLTRIM(_Screen.AppName)+)
+lcTexto,_Screen.DirApp+_Screen.MisErrores.ArchLog,1)

Endtry

y finalmente, cuando termino con todo...

If llHuboError

oConexionActual.Execute(ROLLBACK TRANSACTION)

Messagebox(Se produjo un error interno durante la
grabación.,16,Avise a Sistemas)

Else

oConexionActual.Execute(COMMIT TRANSACTION)

Endif

Esta operatoria nunca me causo los errores que vos mencionas

Tengo otros quilombos (quien no? :)), pero hasta el momento con
SqlServer fueron todas sonrisas...

Saludos,

Pancho

Cordoba

El 24 de mayo de 2011 08:24, Rafael Copquin
rcopq...@ciudad.com.ar mailto:rcopq...@ciudad.com.ar escribió:

Ahora yo tengo una pregunta sobre SQL Server: es el manejo de
transacciones, que es diferente de la forma en que VFP las maneja.



Veamos el ejemplo clásico de una factura. Dos tablas, una
cabecera y otra de detalle.

Yo genero dos cursor adapters vacíos con este código

local cCmd

cCmd = [select * from cabecera where 1=0]
y genero el CA 'curCabecera'  tengo una clase que genera CA ,
pero es un código largo que no viene al caso

cCmd = [select * from detalles where 1=0]
y genero el CA 'curDetalles'

Para hacerla corta, al grabar hago algo así

cCmd = [begin transaction]
sqlexec(nHandle,cCmd)  con lo que le mando al SQL la orden de
iniciar la transacción
Luego

   insert into curCabecera 
  lOK = tableupdate(.t.,.t.,'curCabecera')
  if lOK
 select curFactura  este es un cursor local que opera con
una grilla
 scan all
   scatter name oFac
   insert into curDetalles from name oFac
 endscan
 lOK = tableupdate(.t.,.t.,'curDetalles')
  if lOK
cCmd = 'IF @@TRANCOUNT  0 COMMIT'
  else
   cCmd = 'IF @@TRANCOUNT  0 ROLLBACK'
 endif
  sqlexec(nHandle,cCmd)

Pero sé que a esto le falta una pata

[GUFA] OFF TOPIC TRANSACT SQL

2011-05-23 Por tema Alejandro Paciotti Iacchelli
Estimados: 

 

Estoy haciendo un procedimiento almacenado en SQL SERVER tal que borre un
registro si se da cierta condición, ¿ cómo puedo hacer para que devuelva -1
sino se pudo borrar ?

 

Paso el código:

 

ALTER PROCEDURE [dbo].[SP_BAJA_NODOS] 

@CodigoNodo VARCHAR(15)

 

AS

BEGIN

  SET NOCOUNT ON;

  DECLARE @Resultado INT

  SET @Resultado = -1

  

  SET @Resultado = (SELECT COUNT(CodigoNodo) FROM Nodos WHERE
CodigoPadre = @CodigoNodo)

  

  IF @Resultado = 0

 BEGIN

DELETE FROM Nodos WHERE CodigoNodo = @CodigoNodo

 END

  ELSE

 -- SELECT -1 Esto ya lo probé y no anda.

 -- RETURN -1 Esto tampoco.

END



[GUFA] OFF TOPIC TRANSACT SQL

2011-05-23 Por tema PabloC
Yo utilizo el Return @Resultado y funciona sin problemas

Hago esto desde el un SP que llama a otro

   Declare @Error Int

 

   Execute @Error = USP_Algo

 

If @Error = 0

 

 

Saludos

PabloC

 

De: GUFA@mug.org.ar [mailto:GUFA@mug.org.ar] En nombre de Alejandro Paciotti
Iacchelli
Enviado el: Lunes, 23 de Mayo de 2011 16:13
Para: GUFA List Member
Asunto: [GUFA] OFF TOPIC TRANSACT SQL

 

Estimados: 

 

Estoy haciendo un procedimiento almacenado en SQL SERVER tal que borre un
registro si se da cierta condición, ¿ cómo puedo hacer para que devuelva -1
sino se pudo borrar ?

 

Paso el código:

 

ALTER PROCEDURE [dbo].[SP_BAJA_NODOS] 

@CodigoNodo VARCHAR(15)

 

AS

BEGIN

  SET NOCOUNT ON;

  DECLARE @Resultado INT

  SET @Resultado = -1

  

  SET @Resultado = (SELECT COUNT(CodigoNodo) FROM Nodos WHERE
CodigoPadre = @CodigoNodo)

  

  IF @Resultado = 0

 BEGIN

DELETE FROM Nodos WHERE CodigoNodo = @CodigoNodo

 END

  ELSE

 -- SELECT -1 Esto ya lo probé y no anda.

 -- RETURN -1 Esto tampoco.

END



[GUFA] OFF TOPIC TRANSACT SQL

2011-05-23 Por tema francisco prieto
 Al final

Return @Resultado

Te mando por si las moscas un ejemplo mio

USE [ACE]
GO
/** Object:  StoredProcedure [dbo].[CheckOut]Script Date: 05/23/2011
16:20:01 **/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

/*
 Procedimiento que reserva (check-out) o renueva
 la reserva de un objeto para un usuario
*/
ALTER PROCEDURE [dbo].[CheckOut]
 @TipoObjeto varchar(2),
 @FechaHora datetime,
 @Turno varchar(4),
 @UsuarioId varchar(10),
 @Pudo int OUTPUT
AS

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION

select  @Pudo=COUNT(*) from Bloqueos
WHERE ObjectID = @TipoObjeto+CONVERT(varchar(23),@FechaHora,126)+'/'+@Turno
if @Pudo=0
begin
set @Pudo=1
insert into Bloqueos (objectid,usuarioid,expira)
 values (@TipoObjeto+CONVERT(varchar(23),@FechaHora,126)+'/'+@Turno,
@UsuarioId,DATEADD(mi, 10, GETDATE()))
 end
else
begin
UPDATE Bloqueos
 SET
UsuarioId = @UsuarioId,
Expira = DATEADD(mi, 10, GETDATE()) -- expira en diez minutos
 WHERE
ObjectID = @TipoObjeto+CONVERT(varchar(23),@FechaHora,126)+'/'+@Turno
 AND (Expira IS NULL OR UsuarioID = @UsuarioId)
IF @@ROWCOUNT = 0
begin
 UPDATE Bloqueos
SET
UsuarioId = @UsuarioId,
 Expira = DATEADD(mi, 10, GETDATE()) -- expira en diez minutos
WHERE
 ObjectID = @TipoObjeto+CONVERT(varchar(23),@FechaHora,126)+'/'+@Turno
AND Expira  GETDATE()
 IF @@ROWCOUNT = 0
set @Pudo=0
else
 set @Pudo=2
end
else
 set @Pudo=1
end

COMMIT TRANSACTION

 return @Pudo

Saludos,

Pancho
Cordoba

El 23 de mayo de 2011 16:12, Alejandro Paciotti Iacchelli 
alejandro.pacio...@gmail.com escribió:

 Estimados:



 Estoy haciendo un procedimiento almacenado en SQL SERVER tal que borre un
 registro si se da cierta condición, ¿ cómo puedo hacer para que devuelva -1
 sino se pudo borrar ?



 Paso el código:



 ALTER PROCEDURE [dbo].[SP_BAJA_NODOS]

 @CodigoNodo VARCHAR(15)



 AS

 BEGIN

   SET NOCOUNT ON;

   DECLARE @Resultado INT

   SET @Resultado = -1



   SET @Resultado = (SELECT COUNT(CodigoNodo) FROM Nodos WHERE
 CodigoPadre = @CodigoNodo)



   IF @Resultado = 0

  BEGIN

 DELETE FROM Nodos WHERE CodigoNodo = @CodigoNodo

  END

   ELSE

  -- SELECT -1 Esto ya lo probé y no anda.

  -- RETURN -1 Esto tampoco.

 END



[GUFA] OFF TOPIC TRANSACT SQL

2011-05-23 Por tema Alfonso Arias Lemas
Utilizas RAISERROR..






De: Alejandro Paciotti Iacchelli alejandro.pacio...@gmail.com
Para: GUFA List Member GUFA@mug.org.ar
Enviado: lun,23 mayo, 2011 18:12
Asunto: [GUFA] OFF TOPIC TRANSACT SQL


Estimados: 
 
Estoy haciendo un procedimiento almacenado en SQL SERVER tal que borre un 
registro si se da cierta condición, ¿ cómo puedo hacer para que devuelva -1 
sino 
se pudo borrar ?
 
Paso el código:
 
ALTERPROCEDURE [dbo].[SP_BAJA_NODOS] 
@CodigoNodoVARCHAR(15)
 
AS
BEGIN
  SET NOCOUNT ON;
  DECLARE @Resultado INT
  SET @Resultado = -1
  
  SET @Resultado =(SELECT COUNT(CodigoNodo) FROM Nodos WHERE CodigoPadre = 
@CodigoNodo)
  
  IF @Resultado = 0
     BEGIN
    DELETE FROM Nodos WHERE CodigoNodo = @CodigoNodo
     END
  ELSE
     -- SELECT -1 Esto ya lo probé y no anda.
     -- RETURN -1 Esto tampoco.
END