Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » SQL Server »

Ayuda Con trigger Please!!

Estas en el tema de Ayuda Con trigger Please!! en el foro de SQL Server en Foros del Web. Hola un saludo, soy nuevo en esto del SQL y como tal varias cosas no me salen: Incluyendo el siguiente trigger. Tengo la siguiente tabla: ...
  #1 (permalink)  
Antiguo 03/04/2008, 11:05
jgi
 
Fecha de Ingreso: abril-2008
Mensajes: 8
Antigüedad: 16 años, 1 mes
Puntos: 0
Ayuda Con trigger Please!!

Hola un saludo, soy nuevo en esto del SQL y como tal varias cosas no me salen: Incluyendo el siguiente trigger.

Tengo la siguiente tabla:
CREATE TABLE [dbo].[CA_DOCUMENT_ACTORS](
[document_id] [int] NULL,
[user_id] [varchar](8000) COLLATE Modern_Spanish_CI_AS NULL,
[actors] [varchar](8000) COLLATE Modern_Spanish_CI_AS NULL,
[emiterId] [varchar](8000) COLLATE Modern_Spanish_CI_AS NULL,
[process_id] [int] NULL
) ON [PRIMARY]

Necesito q el trigger se active antes de insertar un nuevo registro cuando el registro tenga un ID_document = a uno existente, entonces concatenar el registro entrante con el q ya existe en la tabla
los campos a concatenar van a ser [user_id] actors] [emiterId]

Para lo cual he diseñado el siguiente trigger pero me sale este error al final:

Msg 156, Level 15, State 1, Procedure TR_UPDATE, Line 68
Incorrect syntax near the keyword 'ELSE'.
No se porque!!!

Bueno ademas q necesito una ayudita de como leer el registro q va a entrar en el INSTEAD OF.

MUCHAS GRACIAS POR SU COLABORACION
-----------

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE TRIGGER TR_UPDATE
ON CA_DOCUMENT_ACTORS
INSTEAD OF INSERT

AS
BEGIN


declare @docId as int
--AS

declare @user_id as varchar(max)
declare @c_user_id as varchar(max)
declare @last_actor_id as varchar(max)
declare @c_last_actor_id as varchar(max)
declare @emitter_id as varchar(max)
declare @c_emitter_id as varchar(max)
declare @processId as INT
declare @c_processId as varchar(max)


BEGIN

set @c_user_id = ''
set @c_last_actor_id = ''
set @c_emitter_id = ''
set @c_processId = ''

SET NOCOUNT ON;



--select * from CA_DOCUMENT_ACTORS

IF EXISTS (select *
from CA_DOCUMENT_ACTORS
where document_id = @docId)

Declare CURSOR1 cursor for
SELECT user_id, actors, emiterId, process_id FROM CA_DOCUMENT_ACTORS WHERE DOCUMENT_ID=@docId
open CURSOR1
fetch next from CURSOR1
into @user_id, @last_actor_id, @emitter_id, @processId

while @@fetch_status = 0
begin

set @c_user_id = @c_user_id + user_id + ', '
set @c_last_actor_id = @c_last_actor_id + @last_actor_id + ', '
set @c_emitter_id = @c_emitter_id + @emitter_id + ', '
set @c_processId = @processId--cast(@processId as varchar(max))

end

close CURSOR1
deallocate CURSOR1

select @c_user_id, @c_last_actor_id, @c_emitter_id, @c_processId

UPDATE CA_DOCUMENT_ACTORS SET USER_ID=SUBSTRING(@c_user_id,0,LEN(@c_user_id)),
ACTORS =SUBSTRING(@last_actor_id,0,LEN(@last_actor_id)),
EMITERID = SUBSTRING(@c_emitter_id,0,LEN(@c_emitter_id)),
PROCESSID=SUBSTRING(@c_processId,0,LEN(@c_processI d))
WHERE "document_id" = @docId
end

ELSE BEGIN
Insert into CA_DOCUMENT_ACTORS values(@docId, @user_id, @last_actor_id, @emitter_id, @processId)

end


END
  #2 (permalink)  
Antiguo 03/04/2008, 12:06
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 10 meses
Puntos: 180
Re: Ayuda Con trigger Please!!

Bueno, primero que todo y ante todo, NO SE RECOMIENDA el uso de cursores y mucho menos en un trigger.

Esta linea es incorrecta

set @c_user_id = @c_user_id + user_id + ', '

IF...ELSE
Impone condiciones en la ejecución de una instrucción Transact-SQL. La instrucción Transact-SQL que sigue a una palabra clave IF y a su condición se ejecuta si la condición se satisface (cuando la expresión booleana devuelve TRUE). La palabra clave opcional ELSE introduce una instrucción Transact-SQL alternativa que se ejecuta cuando la condición IF no se satisface (cuando la expresión booleana devuelve FALSE).

Sintaxis
IF Boolean_expression
{ sql_statement | statement_block }
[ ELSE
{ sql_statement | statement_block } ]

No estas cumpliendo con esta regla en:

ELSE BEGIN
Insert into CA_DOCUMENT_ACTORS values(@docId, @user_id, @last_actor_id, @emitter_id, @processId

Por ultimo, ¿Sabes que puedes traer mas de un registro en tus tablas INSERTED, UPDATED?

¿Donde estas haciendo referencia a estas tablas?
  #3 (permalink)  
Antiguo 03/04/2008, 13:02
jgi
 
Fecha de Ingreso: abril-2008
Mensajes: 8
Antigüedad: 16 años, 1 mes
Puntos: 0
Re: Ayuda Con trigger Please!!

Hola Muchas gracias por responder pronto...(me esta gustando este foro)

mmmm creo q quedé mas confundido... :(

Hice este if con el fin de verificar si el "Document_id" ya existe, si en verdad existe entonces
realizar la operacion de concatenacion (pero esto solo lo he hecho con cursores.. no se otra forma :() se me fue
el begin porque lo intenté sin el y tampoco me funciona

si la condicion es falsa, hará el insert comun y corriente... por favor me dices en q estoy fallando principalmente?

la expresion "set @c_user_id = @c_user_id + user_id + ', ' " la cree para q tome la variable temporal de concatenacion y sume (concatene) la variable del registro

La idea es hacer el disparador para cada insert con el fin de q busque el document_id si lo encuentra, concatenar el nuevo registro (el del insert q disparo el trigger), si no,hacer el insert normal en un nuevo registro...

Muchas Gracias.. Hasta pronto
  #4 (permalink)  
Antiguo 03/04/2008, 15:55
jgi
 
Fecha de Ingreso: abril-2008
Mensajes: 8
Antigüedad: 16 años, 1 mes
Puntos: 0
Re: Ayuda Con trigger Please!!

Hola ya tengo el proccedimiento q busca y concatena..... abajo lo pongo... ahora solo me falta el tigre q lo dispara, ya q el esta en espera del document_ID, pero no se como hacer q el tigre se lo pase antes de que se inserte... hice esto:

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go

-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER TRIGGER [INSERTA]
ON [dbo].[CA_DOCUMENT_ACTORS]
INSTEAD OF insert

AS
BEGIN

DECLARE @document_id AS INT
DECLARE @process_id AS INT
DECLARE @user_id AS VARCHAR(MAX)
DECLARE @actors AS VARCHAR(MAX)
DECLARE @emiterId AS VARCHAR(MAX)


DECLARE cursor2 CURSOR
FOR SELECT [document_id], [user_id], [actors], [emiterId], [process_id] FROM inserted
OPEN cursor2
FETCH NEXT FROM cursor2 INTO @document_id, @user_id, @actors, @emiterId, @process_id
WHILE (@@FETCH_STATUS=0)
close cursor2
deallocate cursor2


PRINT @document_id;


END

El print se lo puse para verificar que este funcionando, pero antes no tenia esto:
close cursor2
deallocate cursor2

y se quedaba mostrandome indefinidamente el Document_ID q insertaba, luego le puse y no funcionó mas...

al final necesito incurstarle este procedimiento q es el q concatena segun el parametro de docid q se ingrese.
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go





-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[conc_busca]
@docId int
AS

declare @user_id as varchar(max)
declare @c_user_id as varchar(max)
declare @last_actor_id as varchar(max)
declare @c_last_actor_id as varchar(max)
declare @emitter_id as varchar(max)
declare @c_emitter_id as varchar(max)
declare @processId as INT
declare @c_processId as varchar(max)


BEGIN

set @c_user_id = ''
set @c_last_actor_id = ''
set @c_emitter_id = ''
set @c_processId = ''

SET NOCOUNT ON;



--select * from CA_DOCUMENT_ACTORS

IF EXISTS (select document_id
from CA_DOCUMENT_ACTORS
where document_id = @docId)
BEGIN
Declare CURSOR1 cursor for
SELECT user_id, actors, emiterId, process_id FROM CA_DOCUMENT_ACTORS WHERE DOCUMENT_ID=@docId
open CURSOR1
fetch next from CURSOR1
into @user_id, @last_actor_id, @emitter_id, @processId

while @@fetch_status = 0
begin

set @c_user_id = @c_user_id + @user_id + ', '
set @c_last_actor_id = @c_last_actor_id + @last_actor_id + ', '
set @c_emitter_id = @c_emitter_id + @emitter_id + ', '
set @c_processId = @processId--cast(@processId as varchar(max))

fetch next from CURSOR1
into @user_id, @last_actor_id, @emitter_id, @processId
end

close CURSOR1
deallocate CURSOR1

select @c_user_id, @c_last_actor_id, @c_emitter_id, @c_processId

UPDATE CA_DOCUMENT_ACTORS SET USER_ID=SUBSTRING(@c_user_id,0,LEN(@c_user_id)),
ACTORS =SUBSTRING(@last_actor_id,0,LEN(@last_actor_id)),
EMITERID = SUBSTRING(@c_emitter_id,0,LEN(@c_emitter_id)),
PROCESS_ID=SUBSTRING(@c_processId,0,LEN(@c_process Id))
WHERE "document_id" = @docId
END

ELSE
BEGIN
Insert into CA_DOCUMENT_ACTORS values(@docId, @user_id, @last_actor_id, @emitter_id, @processId)
END
end

DE NUEVO MUCHAS GRACIAS
  #5 (permalink)  
Antiguo 03/04/2008, 17:25
Avatar de iislas
Colaborador
 
Fecha de Ingreso: julio-2007
Ubicación: Mexico, D.F.
Mensajes: 6.482
Antigüedad: 16 años, 10 meses
Puntos: 180
Re: Ayuda Con trigger Please!!

Veo que sigue entendiendo mal la ejecucion del TRIGGER

"La idea es hacer el disparador para cada insert con el fin de q busque el document_id si lo encuentra"

Si yo hago 1 insert, se ejecuta UNA VEZ el TRIGGER
(en la tabla INSERTED, solo hay UN REGISTRO)

Si hago, 10,000 inserts, se ejecuta UNA VEZ el TRIGGER
(en la tabla INSERTED, hay 10,000 registros)

¿Porque mejor no nos cuenta que es lo que desea hacer y nos pone un ejemplo?

Saludos
  #6 (permalink)  
Antiguo 04/04/2008, 08:06
jgi
 
Fecha de Ingreso: abril-2008
Mensajes: 8
Antigüedad: 16 años, 1 mes
Puntos: 0
Re: Ayuda Con trigger Please!!

Hola de nuevo...

Mira, el inconveniente es el siguiente, tengo esta tabla:

document_id- user_id- actors- emiterId- process_id-

Resulta que esta tabla esta muy mal definida y no tiene llave principal, ni foraneas, sino la insercion la hacen por medio del aplicativo q la diseñaron.

La peticion radica en que hay Varios document_id q digamos q es el campo principal, entonces la idea es concatenar los otros campos a Excepcion del Process_Id, (para q quede un solo document_id)esto ya lo hice con un procedimiento almacenado similar al q puse arriba. Ahora bien, como esto no soluciona el problema (y los señores de desarrollo no quieren cambiar codigo para nada) entonces tengo q realizar un trigger q se dispare en cada insert, que busque en el registro q estan a punto de ingresar el document_ID (Instead of supongo) , si lo encuentra, concatenar los campos del nuevo registro q esta ingresando, junto con el q ya existe (a excepcion de document_id- y process_id-,) pero q si no existe haga un insert normal,
como no se de triggers, estaba ensayando con un procedure q me hace la validacion (Creo q lo puse arriba) hasta q llegué al punto q me pide el parametro del document_id si existe concatena variables, pero como no se leer la filas antes de ser insertadas me ingresa solo las "," (pero la validacion si funciona).
La idea es mezclar el codigo de ese procedimiento en el trigger, pero con su ayudita, ya q como les dije no he encontrado un ejemplo de instead of q lea la fila por entrar, le asigne a cada valor del campo una variable, luego compare con el codigo del procedure q puse arriba (q la idea es no dejarlo aparte sino como parte del disparador), y luego si el document_id ya existe, concatene (update), si no, Inserte normal. Muchas Gracias por su tiempo

PD: El trigger se necesita para cada insert... si se hacen mil inserts, q se dispare mil Veces.. Gracias
  #7 (permalink)  
Antiguo 09/04/2008, 13:51
jgi
 
Fecha de Ingreso: abril-2008
Mensajes: 8
Antigüedad: 16 años, 1 mes
Puntos: 0
Re: Ayuda Con trigger Please!!

Hola, finalmente resolví el Tigre hace un par de días, el resultado es este: (se q hay cosas en definicion q se pueden arreglar para q el codigo sea mas optimo)

Sin embargo ahi lo dejo para quien le pueda interesar.

Gracias...

--------

set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go





-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
CREATE TRIGGER [INSERTA]
ON [dbo].[CA_DOCUMENT_ACTORS]
INSTEAD OF insert

AS
DECLARE @document_id AS INT
declare @user_id as varchar(max)
declare @c_user_id as varchar(max)
declare @leauser_id as varchar(max)

declare @last_actor_id as varchar(max)
declare @c_last_actor_id as varchar(max)
declare @lealast_actor_id as varchar(max)

declare @emitter_id as varchar(max)
declare @c_emitter_id as varchar(max)
declare @leaemitter_id as varchar(max)

declare @processId as INT
declare @c_processId as varchar(max)
declare @leaprocessId as INT

--DECLARE @ret_msg AS VARCHAR(100);


BEGIN
set @c_user_id = ''
set @c_last_actor_id = ''
set @c_emitter_id = ''
set @c_processId = ''

SET NOCOUNT ON; ---

--SET @document_id = SELECT [document_id]FROM inserted

DECLARE cursor2 CURSOR
FOR SELECT [document_id], [user_id], [actors], [emiterId], [process_id] FROM inserted
OPEN cursor2
FETCH NEXT FROM cursor2 INTO @document_id, @user_id, @last_actor_id, @emitter_id, @processId
WHILE (@@FETCH_STATUS=0)
begin
fetch next from CURSOR2
into @document_id, @user_id, @last_actor_id, @emitter_id, @processId
end
close cursor2
deallocate cursor2

IF EXISTS (select document_id
from CA_DOCUMENT_ACTORS
where document_id = @document_id)
BEGIN
Declare CURSOR1 cursor for
SELECT user_id, actors, emiterId, process_id FROM CA_DOCUMENT_ACTORS WHERE DOCUMENT_ID=@document_id
open CURSOR1
fetch next from CURSOR1
into @leauser_id, @lealast_actor_id, @leaemitter_id, @leaprocessId

while @@fetch_status = 0
begin

set @c_user_id = @c_user_id + @leauser_id + ', ' +@user_id --+ ', '
set @c_last_actor_id = @c_last_actor_id + @lealast_actor_id + ', ' + @last_actor_id --+ ', '
set @c_emitter_id = @c_emitter_id + @leaemitter_id + ', ' + @emitter_id --+ ', '
set @c_processId = @processId

fetch next from CURSOR1
into @user_id, @last_actor_id, @emitter_id, @processId
end

close CURSOR1
deallocate CURSOR1

select @c_user_id, @c_last_actor_id, @c_emitter_id, @c_processId

UPDATE CA_DOCUMENT_ACTORS SET USER_ID= @c_user_id,
ACTORS = @c_last_actor_id,
EMITERID = @c_emitter_id,
PROCESS_ID= @c_processId
WHERE "document_id" = @document_id

END

ELSE
BEGIN
Insert into CA_DOCUMENT_ACTORS values(@document_id, @user_id, @last_actor_id, @emitter_id, @processId)
END







-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

-- Insert statements for trigger here

END
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




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