Microsoft quito el soporte de cursores en triggesr??

07/08/2006 - 15:35 por Rodrigo Bedoya | Informe spam
Tengo Una aplicacion bastante robusta y estable en sql2000, pero algunos
clientes pequeños van a tener sql2005 express , mi pregunta es microsoft
quito el soporte de cursores en triggers cuando se ejecutan dinamicamente en
cadenas ?? .. Anexo este ejemplo sencillo pero completo donde se crea un
cursor en un trigger

/*

En este paquete se crean las tablas cabecera2006 y detalle2006

El trigger asociado a la tabla de detalle

Se graba un registro en cabecera y otro en detalle para visualizar el

el error en sql2005 , pero este mismo paquete se corre en sql2000 bien.

*/






GO

- Archivo Detalle --

CREATE TABLE DETALLE2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTERCERO] [char](11) DEFAULT (' '),

[ccuenta] [char](20) DEFAULT (' '),

[nValor] numeric(10,2) DEFAULT (0),

[nItem] int DEFAULT (0),

CONSTRAINT [DETALLE2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC,

[nItem] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

DROP TABLE CABECERA2006

GO

-Archivo Cabecera

CREATE TABLE CABECERA2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTransaccion] [char] (10) DEFAULT (' '),

CONSTRAINT [CABECERA2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

Trigger Tabla Detalle

set ANSI_NULLS ON

set QUOTED_IDENTIFIER OFF

GO

CREATE TRIGGER [dbo].[grabacion] ON [dbo].[DETALLE2006]

FOR INSERT

AS

DECLARE @Cdocumento CHAR(2),

@cNumero CHAR(8),

@dFecha DATETIME,

@cExpresion VARCHAR(200),

@cTransaccion CHAR(10),

@cAno CHAR(4)

SELECT @cDocumento = ins.cDocumento,@cNumero = ins.cNumero,@dFecha =
ins.dFecha FROM INSERTED INS

SET @Cano = LTRIM(RTRIM(STR(YEAR(@dFecha))))

Dependiendo de la fecha se carga la tabla respectiva pueder ser

cabecera2005, cabecera2006 etc, por eso se hace en forma dinamica

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)

Solo es un ejemplo para traer datos de la cabecera y aplicar

algun logica en el trigger

OPEN cabecera

FETCH NEXT FROM cabecera INTO @cTransaccion

CLOSE cabecera

DEALLOCATE cabecera






RETURN

Insertamos Registro Cabecera -

INSERT INTO CABECERA2006 VALUES('RC','9898','05/08/2006','COMPRAS')

GO

/*

Insertamos Registro Detalle

Aqui se ejecuta el trigger de insertar de la tabla detalle2006

y se genera error ,pero en sql2000 no genera error

*/

INSERT INTO DETALLE2006
VALUES('RC','9898','05/08/2006','7528558','1305050',1500000,1);

Todo Esto Funciona super bien en sql2000



Saludos



RODRIGO

Preguntas similare

Leer las respuestas

#1 Maxi
07/08/2006 - 16:50 | Informe spam
Hola, cuantas veces vas a postear esto mismo? microsoft no saco el soporte
de cursores ni mucho menos, yo ya te respondi en anteriores oportunidades,
vos estas declarando el cursor dentro de SQL Dinamico con EXEC y luego
queres usar esa variable afuera, el problema esta ahi no en los cursores ni
en los triggers. O bien repensas el trigger para que no use ni cursores ni
sql dinamico o sino proba usandp sp_executesql en lugar de exec


Salu2
Maxi [MVP SQL SERVER]
www.sqlgurus.org
Speaker INETA
Speaker Culminis


"Rodrigo Bedoya" escribió en el mensaje
news:
Tengo Una aplicacion bastante robusta y estable en sql2000, pero algunos
clientes pequeños van a tener sql2005 express , mi pregunta es microsoft
quito el soporte de cursores en triggers cuando se ejecutan dinamicamente
en cadenas ?? .. Anexo este ejemplo sencillo pero completo donde se crea
un cursor en un trigger

/*

En este paquete se crean las tablas cabecera2006 y detalle2006

El trigger asociado a la tabla de detalle

Se graba un registro en cabecera y otro en detalle para visualizar el

el error en sql2005 , pero este mismo paquete se corre en sql2000 bien.

*/






GO

- Archivo Detalle --

CREATE TABLE DETALLE2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTERCERO] [char](11) DEFAULT (' '),

[ccuenta] [char](20) DEFAULT (' '),

[nValor] numeric(10,2) DEFAULT (0),

[nItem] int DEFAULT (0),

CONSTRAINT [DETALLE2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC,

[nItem] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

DROP TABLE CABECERA2006

GO

-Archivo Cabecera

CREATE TABLE CABECERA2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTransaccion] [char] (10) DEFAULT (' '),

CONSTRAINT [CABECERA2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

Trigger Tabla Detalle

set ANSI_NULLS ON

set QUOTED_IDENTIFIER OFF

GO

CREATE TRIGGER [dbo].[grabacion] ON [dbo].[DETALLE2006]

FOR INSERT

AS

DECLARE @Cdocumento CHAR(2),

@cNumero CHAR(8),

@dFecha DATETIME,

@cExpresion VARCHAR(200),

@cTransaccion CHAR(10),

@cAno CHAR(4)

SELECT @cDocumento = ins.cDocumento,@cNumero = ins.cNumero,@dFecha =
ins.dFecha FROM INSERTED INS

SET @Cano = LTRIM(RTRIM(STR(YEAR(@dFecha))))

Dependiendo de la fecha se carga la tabla respectiva pueder ser

cabecera2005, cabecera2006 etc, por eso se hace en forma dinamica

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)

Solo es un ejemplo para traer datos de la cabecera y aplicar

algun logica en el trigger

OPEN cabecera

FETCH NEXT FROM cabecera INTO @cTransaccion

CLOSE cabecera

DEALLOCATE cabecera






RETURN

Insertamos Registro Cabecera -

INSERT INTO CABECERA2006 VALUES('RC','9898','05/08/2006','COMPRAS')

GO

/*

Insertamos Registro Detalle

Aqui se ejecuta el trigger de insertar de la tabla detalle2006

y se genera error ,pero en sql2000 no genera error

*/

INSERT INTO DETALLE2006
VALUES('RC','9898','05/08/2006','7528558','1305050',1500000,1);

Todo Esto Funciona super bien en sql2000



Saludos



RODRIGO






Respuesta Responder a este mensaje
#2 Rodrigo Bedoya
07/08/2006 - 17:23 | Informe spam
Hola Maxi
Es que una situacion tan simple que funciona superbien en sql2000 ,deje de
funcionar en sql2005 a razon de que ?.
La misma aplicacion la tenemos en ORACLE y todo perfecto.
Y es asi de simple definas un cursor con sql dinamico en 2000 con triggers y
crea el cursor , pero lo defines en sql2005 y falla no crea el cursor , no
es solo de variables

Rodrigo






Ya probe usando sp_exectessql y el mismo error
"Maxi" wrote in message
news:
Hola, cuantas veces vas a postear esto mismo? microsoft no saco el soporte
de cursores ni mucho menos, yo ya te respondi en anteriores oportunidades,
vos estas declarando el cursor dentro de SQL Dinamico con EXEC y luego
queres usar esa variable afuera, el problema esta ahi no en los cursores
ni en los triggers. O bien repensas el trigger para que no use ni cursores
ni sql dinamico o sino proba usandp sp_executesql en lugar de exec


Salu2
Maxi [MVP SQL SERVER]
www.sqlgurus.org
Speaker INETA
Speaker Culminis


"Rodrigo Bedoya" escribió en el mensaje
news:
Tengo Una aplicacion bastante robusta y estable en sql2000, pero algunos
clientes pequeños van a tener sql2005 express , mi pregunta es microsoft
quito el soporte de cursores en triggers cuando se ejecutan dinamicamente
en cadenas ?? .. Anexo este ejemplo sencillo pero completo donde se
crea un cursor en un trigger

/*

En este paquete se crean las tablas cabecera2006 y detalle2006

El trigger asociado a la tabla de detalle

Se graba un registro en cabecera y otro en detalle para visualizar el

el error en sql2005 , pero este mismo paquete se corre en sql2000 bien.

*/






GO

- Archivo Detalle --

CREATE TABLE DETALLE2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTERCERO] [char](11) DEFAULT (' '),

[ccuenta] [char](20) DEFAULT (' '),

[nValor] numeric(10,2) DEFAULT (0),

[nItem] int DEFAULT (0),

CONSTRAINT [DETALLE2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC,

[nItem] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

DROP TABLE CABECERA2006

GO

-Archivo Cabecera

CREATE TABLE CABECERA2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTransaccion] [char] (10) DEFAULT (' '),

CONSTRAINT [CABECERA2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

Trigger Tabla Detalle

set ANSI_NULLS ON

set QUOTED_IDENTIFIER OFF

GO

CREATE TRIGGER [dbo].[grabacion] ON [dbo].[DETALLE2006]

FOR INSERT

AS

DECLARE @Cdocumento CHAR(2),

@cNumero CHAR(8),

@dFecha DATETIME,

@cExpresion VARCHAR(200),

@cTransaccion CHAR(10),

@cAno CHAR(4)

SELECT @cDocumento = ins.cDocumento,@cNumero = ins.cNumero,@dFecha =
ins.dFecha FROM INSERTED INS

SET @Cano = LTRIM(RTRIM(STR(YEAR(@dFecha))))

Dependiendo de la fecha se carga la tabla respectiva pueder ser

cabecera2005, cabecera2006 etc, por eso se hace en forma dinamica

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)

Solo es un ejemplo para traer datos de la cabecera y aplicar

algun logica en el trigger

OPEN cabecera

FETCH NEXT FROM cabecera INTO @cTransaccion

CLOSE cabecera

DEALLOCATE cabecera






RETURN

Insertamos Registro Cabecera -

INSERT INTO CABECERA2006 VALUES('RC','9898','05/08/2006','COMPRAS')

GO

/*

Insertamos Registro Detalle

Aqui se ejecuta el trigger de insertar de la tabla detalle2006

y se genera error ,pero en sql2000 no genera error

*/

INSERT INTO DETALLE2006
VALUES('RC','9898','05/08/2006','7528558','1305050',1500000,1);

Todo Esto Funciona super bien en sql2000



Saludos



RODRIGO










Respuesta Responder a este mensaje
#3 Maxi
07/08/2006 - 17:39 | Informe spam
Hola, donde estas definiendo el cursor? no hay un declare fuera de EXEC mahi
esta el problema, el compilador al no tener el declare fuera te esta
marcando un error en 2005


Salu2
Maxi [MVP SQL SERVER]
www.sqlgurus.org
Speaker INETA
Speaker Culminis


"Rodrigo Bedoya" escribió en el mensaje
news:ev5Q$
Hola Maxi
Es que una situacion tan simple que funciona superbien en sql2000 ,deje de
funcionar en sql2005 a razon de que ?.
La misma aplicacion la tenemos en ORACLE y todo perfecto.
Y es asi de simple definas un cursor con sql dinamico en 2000 con triggers
y crea el cursor , pero lo defines en sql2005 y falla no crea el cursor ,
no es solo de variables

Rodrigo






Ya probe usando sp_exectessql y el mismo error
"Maxi" wrote in message
news:
Hola, cuantas veces vas a postear esto mismo? microsoft no saco el
soporte de cursores ni mucho menos, yo ya te respondi en anteriores
oportunidades, vos estas declarando el cursor dentro de SQL Dinamico con
EXEC y luego queres usar esa variable afuera, el problema esta ahi no en
los cursores ni en los triggers. O bien repensas el trigger para que no
use ni cursores ni sql dinamico o sino proba usandp sp_executesql en
lugar de exec


Salu2
Maxi [MVP SQL SERVER]
www.sqlgurus.org
Speaker INETA
Speaker Culminis


"Rodrigo Bedoya" escribió en el mensaje
news:
Tengo Una aplicacion bastante robusta y estable en sql2000, pero algunos
clientes pequeños van a tener sql2005 express , mi pregunta es microsoft
quito el soporte de cursores en triggers cuando se ejecutan
dinamicamente en cadenas ?? .. Anexo este ejemplo sencillo pero
completo donde se crea un cursor en un trigger

/*

En este paquete se crean las tablas cabecera2006 y detalle2006

El trigger asociado a la tabla de detalle

Se graba un registro en cabecera y otro en detalle para visualizar el

el error en sql2005 , pero este mismo paquete se corre en sql2000 bien.

*/






GO

- Archivo Detalle --

CREATE TABLE DETALLE2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTERCERO] [char](11) DEFAULT (' '),

[ccuenta] [char](20) DEFAULT (' '),

[nValor] numeric(10,2) DEFAULT (0),

[nItem] int DEFAULT (0),

CONSTRAINT [DETALLE2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC,

[nItem] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

DROP TABLE CABECERA2006

GO

-Archivo Cabecera

CREATE TABLE CABECERA2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTransaccion] [char] (10) DEFAULT (' '),

CONSTRAINT [CABECERA2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

Trigger Tabla Detalle

set ANSI_NULLS ON

set QUOTED_IDENTIFIER OFF

GO

CREATE TRIGGER [dbo].[grabacion] ON [dbo].[DETALLE2006]

FOR INSERT

AS

DECLARE @Cdocumento CHAR(2),

@cNumero CHAR(8),

@dFecha DATETIME,

@cExpresion VARCHAR(200),

@cTransaccion CHAR(10),

@cAno CHAR(4)

SELECT @cDocumento = ins.cDocumento,@cNumero = ins.cNumero,@dFecha =
ins.dFecha FROM INSERTED INS

SET @Cano = LTRIM(RTRIM(STR(YEAR(@dFecha))))

Dependiendo de la fecha se carga la tabla respectiva pueder ser

cabecera2005, cabecera2006 etc, por eso se hace en forma dinamica

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)

Solo es un ejemplo para traer datos de la cabecera y aplicar

algun logica en el trigger

OPEN cabecera

FETCH NEXT FROM cabecera INTO @cTransaccion

CLOSE cabecera

DEALLOCATE cabecera






RETURN

Insertamos Registro Cabecera -

INSERT INTO CABECERA2006 VALUES('RC','9898','05/08/2006','COMPRAS')

GO

/*

Insertamos Registro Detalle

Aqui se ejecuta el trigger de insertar de la tabla detalle2006

y se genera error ,pero en sql2000 no genera error

*/

INSERT INTO DETALLE2006
VALUES('RC','9898','05/08/2006','7528558','1305050',1500000,1);

Todo Esto Funciona super bien en sql2000



Saludos



RODRIGO














Respuesta Responder a este mensaje
#4 Alejandro Mesa
07/08/2006 - 21:02 | Informe spam
Rodrigo,

En SQL Server 2000 y 2005, existe una opcion a nivel de db, para especificar
que tipo de cursor se crea (local o global) cuando esta opcion es omitida en
la sentencia que declara el cursor (Fijate en la sentencia DECLARE que usas).
El nombre de la opcion a nivel de db se llama "default to local cursor" y en
la version 2000 es "false" por defecto, mientras que en la version 2005 es
"true". Cuando declaras el cursor en el trigger:

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)



SQL Server 2000 lo declara como global y por eso puedes abrirlo, hacer
"fetch", etc. En cambio, en 2005 se esta declarando como "local" y por eso da
error al referenciarlo en el trigger.

La solucion es que declares el tipo de cursor explicitamente y que no bases
tu programa en el comportamiento interno de SQL Server, o que cambies el
valor de la opcion a nivel de database usando el procedimineto "sp_dboption"
o la sentencia "alter database".

SET @cExpresion="
DECLARE cabecera CURSOR
GLOBAL <-- BUENA PRACTICA
FOR
SELECT cTransaccion
FROM cabecera" + @Cano +
" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)
...


AMB


"Rodrigo Bedoya" wrote:

Tengo Una aplicacion bastante robusta y estable en sql2000, pero algunos
clientes pequeños van a tener sql2005 express , mi pregunta es microsoft
quito el soporte de cursores en triggers cuando se ejecutan dinamicamente en
cadenas ?? .. Anexo este ejemplo sencillo pero completo donde se crea un
cursor en un trigger

/*

En este paquete se crean las tablas cabecera2006 y detalle2006

El trigger asociado a la tabla de detalle

Se graba un registro en cabecera y otro en detalle para visualizar el

el error en sql2005 , pero este mismo paquete se corre en sql2000 bien.

*/






GO

- Archivo Detalle --

CREATE TABLE DETALLE2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTERCERO] [char](11) DEFAULT (' '),

[ccuenta] [char](20) DEFAULT (' '),

[nValor] numeric(10,2) DEFAULT (0),

[nItem] int DEFAULT (0),

CONSTRAINT [DETALLE2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC,

[nItem] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

DROP TABLE CABECERA2006

GO

-Archivo Cabecera

CREATE TABLE CABECERA2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTransaccion] [char] (10) DEFAULT (' '),

CONSTRAINT [CABECERA2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

Trigger Tabla Detalle

set ANSI_NULLS ON

set QUOTED_IDENTIFIER OFF

GO

CREATE TRIGGER [dbo].[grabacion] ON [dbo].[DETALLE2006]

FOR INSERT

AS

DECLARE @Cdocumento CHAR(2),

@cNumero CHAR(8),

@dFecha DATETIME,

@cExpresion VARCHAR(200),

@cTransaccion CHAR(10),

@cAno CHAR(4)

SELECT @cDocumento = ins.cDocumento,@cNumero = ins.cNumero,@dFecha =
ins.dFecha FROM INSERTED INS

SET @Cano = LTRIM(RTRIM(STR(YEAR(@dFecha))))

Dependiendo de la fecha se carga la tabla respectiva pueder ser

cabecera2005, cabecera2006 etc, por eso se hace en forma dinamica

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)

Solo es un ejemplo para traer datos de la cabecera y aplicar

algun logica en el trigger

OPEN cabecera

FETCH NEXT FROM cabecera INTO @cTransaccion

CLOSE cabecera

DEALLOCATE cabecera






RETURN

Insertamos Registro Cabecera -

INSERT INTO CABECERA2006 VALUES('RC','9898','05/08/2006','COMPRAS')

GO

/*

Insertamos Registro Detalle

Aqui se ejecuta el trigger de insertar de la tabla detalle2006

y se genera error ,pero en sql2000 no genera error

*/

INSERT INTO DETALLE2006
VALUES('RC','9898','05/08/2006','7528558','1305050',1500000,1);

Todo Esto Funciona super bien en sql2000



Saludos



RODRIGO







Respuesta Responder a este mensaje
#5 Rodrigo Bedoya
08/08/2006 - 04:11 | Informe spam
Hola Alejandro y/o Maxi

Gracias por contestar pero la verdad , este problema se me volvio critico.
Tambien hice el cambio del atributo cursor global pero continua el error.
sp_dboption @dbname='dbadn',@optname='default to local
cursor',@optvalue='FALSE'

La razon por la que no puedo crear el cursor en forma directa , lo cual
funciona ,es por que mis tablas
son anuales (Cabecera2006,Cabecera2005 etc)

Declare cabecera CURSOR FOR SELECT ctransaccion FROM cabecera2006 where
cdocumento=@cdocumento and cnumero=@cnumero
Luego hago el open cabecera, y perfecto.

Al declararla en forma dinamica la creacion del cursor falla

SET @cExpresion="DECLARE cabecera CURSOR GLOBAL FOR SELECT cTransaccion FROM
cabecera"+@Cano+
" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"
EXECUTE(@cExpresion)

Hago el OPen ... error
Msg 16958, Level 16, State 3, Procedure grabar, Line 34

No se pudo completar la operación de cursor porque las opciones establecidas
cambiaron desde que se declaró el cursor.



Lo que indica que el problema se da es por la expresion sql dinamico , algo
paso entre las versiones
2000 y 2005 que a un esta por resolver..

Gracias a todos , y quisiera que si pueden probar el script que he anexado
varias veces para alguno de ustedes puede vivirlo


RODRIGO






"Alejandro Mesa" wrote in message
news:
Rodrigo,

En SQL Server 2000 y 2005, existe una opcion a nivel de db, para
especificar
que tipo de cursor se crea (local o global) cuando esta opcion es omitida
en
la sentencia que declara el cursor (Fijate en la sentencia DECLARE que
usas).
El nombre de la opcion a nivel de db se llama "default to local cursor" y
en
la version 2000 es "false" por defecto, mientras que en la version 2005 es
"true". Cuando declaras el cursor en el trigger:

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)



SQL Server 2000 lo declara como global y por eso puedes abrirlo, hacer
"fetch", etc. En cambio, en 2005 se esta declarando como "local" y por eso
da
error al referenciarlo en el trigger.

La solucion es que declares el tipo de cursor explicitamente y que no
bases
tu programa en el comportamiento interno de SQL Server, o que cambies el
valor de la opcion a nivel de database usando el procedimineto
"sp_dboption"
o la sentencia "alter database".

SET @cExpresion="
DECLARE cabecera CURSOR
GLOBAL <-- BUENA PRACTICA
FOR
SELECT cTransaccion
FROM cabecera" + @Cano +
" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)
...


AMB


"Rodrigo Bedoya" wrote:

Tengo Una aplicacion bastante robusta y estable en sql2000, pero algunos
clientes pequeños van a tener sql2005 express , mi pregunta es microsoft
quito el soporte de cursores en triggers cuando se ejecutan dinamicamente
en
cadenas ?? .. Anexo este ejemplo sencillo pero completo donde se crea
un
cursor en un trigger

/*

En este paquete se crean las tablas cabecera2006 y detalle2006

El trigger asociado a la tabla de detalle

Se graba un registro en cabecera y otro en detalle para visualizar el

el error en sql2005 , pero este mismo paquete se corre en sql2000 bien.

*/






GO

- Archivo Detalle --

CREATE TABLE DETALLE2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTERCERO] [char](11) DEFAULT (' '),

[ccuenta] [char](20) DEFAULT (' '),

[nValor] numeric(10,2) DEFAULT (0),

[nItem] int DEFAULT (0),

CONSTRAINT [DETALLE2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC,

[nItem] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

DROP TABLE CABECERA2006

GO

-Archivo Cabecera

CREATE TABLE CABECERA2006(

[cDocumento] [char](2) DEFAULT (' '),

[cNumero] [char](8) DEFAULT (' '),

[dFecha] [datetime] DEFAULT (' '),

[cTransaccion] [char] (10) DEFAULT (' '),

CONSTRAINT [CABECERA2006_] PRIMARY KEY NONCLUSTERED

(

[cDOCUMENTO] ASC,

[cNumero] ASC

)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]

) ON [PRIMARY]

GO

Trigger Tabla Detalle

set ANSI_NULLS ON

set QUOTED_IDENTIFIER OFF

GO

CREATE TRIGGER [dbo].[grabacion] ON [dbo].[DETALLE2006]

FOR INSERT

AS

DECLARE @Cdocumento CHAR(2),

@cNumero CHAR(8),

@dFecha DATETIME,

@cExpresion VARCHAR(200),

@cTransaccion CHAR(10),

@cAno CHAR(4)

SELECT @cDocumento = ins.cDocumento,@cNumero = ins.cNumero,@dFecha >> ins.dFecha FROM INSERTED INS

SET @Cano = LTRIM(RTRIM(STR(YEAR(@dFecha))))

Dependiendo de la fecha se carga la tabla respectiva pueder ser

cabecera2005, cabecera2006 etc, por eso se hace en forma dinamica

SET @cExpresion="DECLARE cabecera CURSOR FOR SELECT cTransaccion FROM
cabecera"+@Cano+

" WHERE cDocumento='"+@cDOCUMENTO+"' AND cNumero='"+@cNumero+"'"

EXECUTE(@cExpresion)

Solo es un ejemplo para traer datos de la cabecera y aplicar

algun logica en el trigger

OPEN cabecera

FETCH NEXT FROM cabecera INTO @cTransaccion

CLOSE cabecera

DEALLOCATE cabecera






RETURN

Insertamos Registro Cabecera -

INSERT INTO CABECERA2006 VALUES('RC','9898','05/08/2006','COMPRAS')

GO

/*

Insertamos Registro Detalle

Aqui se ejecuta el trigger de insertar de la tabla detalle2006

y se genera error ,pero en sql2000 no genera error

*/

INSERT INTO DETALLE2006
VALUES('RC','9898','05/08/2006','7528558','1305050',1500000,1);

Todo Esto Funciona super bien en sql2000



Saludos



RODRIGO







Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida