所以小伙子们,我已经采取了预先设定的触发器并尝试在其上添加光标,因此它将逐行更新,不知何故我的光标进入循环......我是新手SQL语言仍然有很多疑问......我想知道这里是否有人可以帮助我...这里是代码:
ALTER TRIGGER TGFUNALTGROUP ON PFUNFPTO
FOR UPDATE
AS
set xact_abort on
DECLARE
@PESS_ID NUMERIC(19),
@PESS_NOME VARCHAR(100),
@PESS_NOMEANTIGO VARCHAR(100),
@PESS_NOMEABREVIADO VARCHAR(50),
@PESS_NOMEABREVIADOANTIGO VARCHAR(50),
@MATR_ID NUMERIC(19),
@MATR_MATRICULA VARCHAR(30),
@MATR_TELEFONE VARCHAR(20),
@MATR_TELEFONEANTIGO VARCHAR(20),
@MATR_RAMALPRINCIPAL VARCHAR(10),
@MATR_RAMALPRINCIPALANTIGO VARCHAR(10),
@MATR_RAMALSECUNDARIO VARCHAR(10),
@MATR_RAMALSECUNDARIOANTIGO VARCHAR(10),
@MATR_FUNCAO VARCHAR(50),
@MATR_FUNCAOANTIGO VARCHAR(50),
@MATR_ATIVO VARCHAR(1),
@EMPR_ID NUMERIC(6),
@LOTA_ID NUMERIC(6),
@CTRF_ID NUMERIC(6),
@DFFUNDATADEMISSAO DATETIME,
@DFFUNDATADEMISSAOANTIGO DATETIME,
@DFEMPCODIGO VARCHAR(5),
@DFORGCODIGO VARCHAR(20),
@DFEMPCODIGOANTIGO VARCHAR(5),
@DFORGCODIGOANTIGO VARCHAR(20),
@DFCTRCODIGO VARCHAR(2),
@DFCTRCODIGOANTIGO VARCHAR(2)
BEGIN
-- Carrega os dados alterados
DECLARE c_UPDATE CURSOR
FAST_FORWARD
FOR
SELECT DFFUNNOME,
DFFUNABREVIADO,
RTRIM(CONVERT(VARCHAR(15),CONVERT(NUMERIC(15),DFFUNCRACHA))),
DFFUNTELEFONE,
DFFUNRAMALPRI,
DFFUNRAMALSEC,
DFFUNFUNCAO,
DFFUNATIVO,
DFFUNDATADEMISSAO,
DFEMPCODIGO,
DFORGCODIGO,
DFCTRCODIGO
FROM INSERTED
OPEN c_UPDATE
FETCH NEXT FROM c_UPDATE INTO
@PESS_NOME,
@PESS_NOMEABREVIADO,
@MATR_MATRICULA,
@MATR_TELEFONE,
@MATR_RAMALPRINCIPAL,
@MATR_RAMALSECUNDARIO,
@MATR_FUNCAO,
@MATR_ATIVO,
@DFFUNDATADEMISSAO,
@DFEMPCODIGO,
@DFORGCODIGO,
@DFCTRCODIGO
DECLARE c_UPDATED CURSOR
FAST_FORWARD
FOR
SELECT DFFUNNOME,
DFFUNABREVIADO,
DFFUNTELEFONE,
DFFUNRAMALPRI,
DFFUNRAMALSEC,
DFFUNFUNCAO,
DFFUNDATADEMISSAO,
DFEMPCODIGO,
DFORGCODIGO,
DFCTRCODIGO
FROM DELETED
OPEN c_UPDATED
FETCH NEXT FROM c_UPDATED INTO
@PESS_NOMEANTIGO,
@PESS_NOMEABREVIADOANTIGO,
@MATR_TELEFONEANTIGO,
@MATR_RAMALPRINCIPALANTIGO,
@MATR_RAMALSECUNDARIOANTIGO,
@MATR_FUNCAOANTIGO,
@DFFUNDATADEMISSAOANTIGO,
@DFEMPCODIGOANTIGO,
@DFORGCODIGOANTIGO,
@DFCTRCODIGOANTIGO
WHILE @@FETCH_STATUS <> -1
-- Verifica se alterou alguma informação integrada
BEGIN
IF @PESS_NOMEANTIGO<>@PESS_NOME
OR @PESS_NOMEABREVIADOANTIGO <> @PESS_NOMEABREVIADO
OR @MATR_TELEFONEANTIGO <> @MATR_TELEFONE
OR @MATR_RAMALPRINCIPALANTIGO <> @MATR_RAMALPRINCIPAL
OR @MATR_RAMALSECUNDARIOANTIGO <> @MATR_RAMALSECUNDARIO
OR @DFFUNDATADEMISSAOANTIGO <> @DFFUNDATADEMISSAO
OR @DFEMPCODIGOANTIGO <> @DFEMPCODIGO
OR @DFORGCODIGOANTIGO <> @DFORGCODIGO
OR @DFCTRCODIGOANTIGO <> @DFCTRCODIGO
BEGIN
-- Determina o id do Matriculado
SET @MATR_ID = 0
SET @PESS_ID = 0
SELECT @MATR_ID = MATR_ID, @PESS_ID = PESS_ID
FROM MATRICULADO
WHERE EMPR_GRUPO = 1
AND MATR_MATRICULA = @MATR_MATRICULA
-- Converte valores
IF @DFFUNDATADEMISSAO = '1899-30-12' --CONVERT(DATETIME,'30/12/1899',101)
SET @MATR_ATIVO = '1'
ELSE
SET @MATR_ATIVO = '0'
-- Se encontrou o Matriculado atualiza os dados
IF @MATR_ID <> 0 AND @PESS_ID <> 0
BEGIN
UPDATE PESSOA SET
PESS_NOME = @PESS_NOME,
PESS_NOMEABREVIADO = @PESS_NOMEABREVIADO,
PESS_NOMEFONETICO = @PESS_NOME
WHERE PESS_ID = @PESS_ID
UPDATE MATRICULADO SET
MATR_TELEFONE = @MATR_TELEFONE,
MATR_RAMALPRINCIPAL = @MATR_RAMALPRINCIPAL,
MATR_RAMALSECUNDARIO = @MATR_RAMALSECUNDARIO,
MATR_FUNCAO = @MATR_FUNCAO,
MATR_ATIVO = @MATR_ATIVO
WHERE MATR_ID = @MATR_ID
-- Se mudou os dados de empresa e orgão gera uma nova alocação
IF @DFEMPCODIGO <> @DFEMPCODIGOANTIGO OR @DFORGCODIGO <> @DFORGCODIGOANTIGO
BEGIN
-- Verifica se a empresa e orgão do Forponto existem no Foracesso
SET @LOTA_ID = 0;
SET @EMPR_ID = 0;
SELECT @LOTA_ID = LOTA_ID
FROM LOTACAO
WHERE LOTA_SIGLA = @DFORGCODIGO
SELECT @EMPR_ID = EMPR_ID
FROM EMPRESA
WHERE EMPR_CODIGO = @DFEMPCODIGO
IF @LOTA_ID <> 0 AND @EMPR_ID <> 0
BEGIN
-- limpa os registros de alocação posteriores a data atual
DELETE FROM MATRICULADO_ALOCACAO
WHERE MATR_ID = @MATR_ID
AND MAAL_INICIO >= CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101)
-- Encerra a alocação atual
UPDATE MATRICULADO_ALOCACAO
SET MAAL_TERMINO = DATEADD(mi,-1,CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101))
WHERE MATR_ID = @MATR_ID
AND MAAL_INICIO < CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101)
AND (MAAL_TERMINO >= CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101)
OR MAAL_TERMINO IS NULL
)
-- Inclui a nova alocação
INSERT INTO MATRICULADO_ALOCACAO
(MATR_ID, MAAL_INICIO, LOTA_ID, EMPR_ID) VALUES
(@MATR_ID, CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101),@LOTA_ID, @EMPR_ID)
END
END
-- Se mudou os dados de categoria de refeição gera uma nova associação
IF @DFCTRCODIGO <> @DFCTRCODIGOANTIGO
BEGIN
-- limpa os registros de categoria refeição posteriores a data atual
DELETE FROM MATRICULADO_CATEG_REFEICAO
WHERE MATR_ID = @MATR_ID
AND MACT_INICIO >= CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101)
-- Encerra a alocação atual
UPDATE MATRICULADO_CATEG_REFEICAO
SET MACT_TERMINO = DATEADD(mi,-1,CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101))
WHERE MATR_ID = @MATR_ID
AND MACT_INICIO < CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101)
AND (MACT_TERMINO >= CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101)
OR MACT_TERMINO IS NULL)
-- -- Inclui a nova alocação
SET @CTRF_ID = 0
SELECT @CTRF_ID = CTRF_ID
FROM CATEGORIA_REFEICAO
WHERE CTRF_DESCRICAO = ( SELECT UPPER(DFCTRDESCRICAO) FROM PCTRFPTO WHERE DFCTRCODIGO = @DFCTRCODIGO)
IF (@CTRF_ID <> 0)
BEGIN
INSERT INTO MATRICULADO_CATEG_REFEICAO
(MATR_ID, CTRF_ID, MACT_INICIO) VALUES
(@MATR_ID, @CTRF_ID,CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),101),101))
END
END
END
END
END
END
CLOSE c_UPDATE
CLOSE c_UPDATED
DEALLOCATE c_UPDATE
DEALLOCATE c_UPDATED
答案 0 :(得分:0)
你需要在WHILE循环中有另一个FETCH NEXT语句来获取下一行。否则@@ FETCH_STATUS永远不会改变,你将永远陷入循环中。
答案 1 :(得分:0)
光标是邪恶使用而不是CROSS APPLY,不要将基于集合的技术用于基于非集合的功能。
以下是如何应用它的链接:
http://www.codeproject.com/Tips/654894/How-to-Use-Cross-Apply-Instead-of-Cursors-in-SQL-S