Member 14565355 Ответов: 1

Неверный синтаксис рядом с ключевым словом "триггер".


Я создаю процедуру для создания триггеров. Я устанавливаю коды для создания триггеров в переменной. Я использовал двойные одинарные кавычки для некоторых кодов, которые имеют одинарные кавычки.

Это и есть ошибки:
Msg 156, Уровень 15, Состояние 1, Строка 1
Неверный синтаксис рядом с ключевым словом "триггер".
Msg 102, Уровень 15, Состояние 1, Линия 107
Неправильный синтаксис рядом с "QUO".


Вот вам процессуальный кодекс:

USE [RCMSDB]
GO
/****** Object:  StoredProcedure [dbo].[CreateAuditTrigger]    Script Date: 5/29/2020 7:51:51 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author:		Jemanoid
-- Create date: 05-08-2020
-- Description:	Wawawiwow
-- =============================================
ALTER PROCEDURE [dbo].[CreateAuditTrigger] 
	@TableName nvarchar(50),
	@PrimaryKeyId nvarchar(50)
AS
	BEGIN

	DECLARE @sqlTrigger1 nvarchar(max);

	SET @sqlTrigger1 = 'CREATE TRIGGER trg_Audit_' + @TableName + ' 
			ON ' + @TableName + '
			FOR INSERT, UPDATE, DELETE
			AS
			BEGIN
			SET NOCOUNT ON;

			DECLARE @sql VARCHAR(5000)
         ,@sqlInserted NVARCHAR(500)
         ,@sqlDeleted NVARCHAR(500)
         ,@NewValue NVARCHAR(100)
         ,@OldValue NVARCHAR(100)
         ,@UpdatedBy VARCHAR(50)
         ,@ParmDefinitionD NVARCHAR(500)
         ,@ParmDefinitionI NVARCHAR(500)
         ,@TABLE_NAME VARCHAR(100)
         ,@COLUMN_NAME VARCHAR(100)
         ,@modifiedColumnsList NVARCHAR(4000)
         ,@ColumnListItem NVARCHAR(500)
         ,@Pos INT
         ,@RecordPk VARCHAR(50)
         ,@RecordPkName VARCHAR(50)
		 ,@RecordPKDelete VARCHAR(50);

			SELECT * INTO #deleted FROM deleted;
			SELECT * INTO #Inserted FROM inserted;;
	
	SET @TABLE_NAME = ' + @TableName + ';

	SELECT @UpdatedBy = @@SERVERNAME;
  	SELECT @RecordPk = @PrimaryKeyId FROM inserted;
	SELECT @RecordPkDelete = @PrimaryKeyId FROM deleted;


	SET @RecordPkName = ''Id'';
	SET @modifiedColumnsList = STUFF((SELECT '','' + name FROM sys.columns
    WHERE object_id = OBJECT_ID(@TABLE_NAME) AND SUBSTRING(COLUMNS_UPDATED(),
    ((column_id - 1) / 8 + 1), 1) & (POWER(2, ((column_id - 1) % 8 + 1) - 1)) 
	= POWER(2, (column_id - 1) % 8) FOR XML PATH ('''')), 1, 1, '''');

	BEGIN
			DECLARE @Action as char(6);
			SET @Action = (CASE WHEN EXISTS(SELECT * FROM INSERTED)
                         AND EXISTS(SELECT * FROM DELETED)
                        THEN ''UPDATE''
                        WHEN EXISTS(SELECT * FROM INSERTED)
                        THEN ''INSERT''
                        WHEN EXISTS(SELECT * FROM DELETED)
                        THEN ''DELETE''
                        ELSE NULL   
                    END);

	  IF EXISTS(SELECT * FROM DELETED)
		INSERT INTO [dbo].[AuditDataChanges]
                                ([TableName]
                                ,[RecordPK]
								,[Action]
                                ,[UpdatedBy])
                                VALUES
                                (@TABLE_NAME
                                ,CAST(@RecordPKDelete as int)
								,@Action
                                ,@UpdatedBy)
	END;

	WHILE LEN(@modifiedColumnsList) > 0
	BEGIN
		SET @Pos = CHARINDEX('','', @modifiedColumnsList);
		IF @Pos = 0
		BEGIN
		SET @ColumnListItem = @modifiedColumnsList;
		END;
		ELSE
		BEGIN
		SET @ColumnListItem = SUBSTRING(@modifiedColumnsList, 1,
		@Pos - 1);
		END;

		SET @COLUMN_NAME = @ColumnListItem;
		SET @ParmDefinitionD = N''@OldValueOut NVARCHAR(100) OUTPUT'';
		SET @ParmDefinitionI = N''@NewValueOut NVARCHAR(100) OUTPUT'';
		SET @sqlDeleted = N''SELECT @OldValueOut='' + @COLUMN_NAME
		+ '' FROM #deleted where '' + @RecordPkName + ''=''
		+ CONVERT(VARCHAR(50), @RecordPk);
		SET @sqlInserted = N''SELECT @NewValueOut='' + @COLUMN_NAME
		+ '' FROM #Inserted where '' + @RecordPkName + ''=''
		+ CONVERT(VARCHAR(50), @RecordPk);
		EXECUTE sp_executesql @sqlDeleted
                       ,@ParmDefinitionD
                       ,@OldValueOut = @OldValue OUTPUT;
		EXECUTE sp_executesql @sqlInserted
                       ,@ParmDefinitionI
                       ,@NewValueOut = @NewValue OUTPUT;

		IF (LTRIM(RTRIM(@NewValue)) != LTRIM(RTRIM(@OldValue)))
		SET @sql = ''INSERT INTO [dbo].[AuditDataChanges]
                                               ([TableName]
                                               ,[RecordPK]				 
                                               ,[Action]
                                               ,[ColumnName]
                                               ,[OldValue]
                                               ,[NewValue]
                                               ,[UpdatedBy])
                                         VALUES
                                               ('' + QUOTENAME(@TABLE_NAME, '''') + ''
                                               ,'' + QUOTENAME(@RecordPk, '''') + ''
					       ,'' + QUOTENAME(@Action, '''') + ''
                                               ,'' + QUOTENAME(@COLUMN_NAME, '''') + ''
                                               ,'' + QUOTENAME(@OldValue, '''') + ''
                                               ,'' + QUOTENAME(@NewValue, '''') + ''
                                               ,'' + QUOTENAME(@UpdatedBy, '''') + '')'';
		EXEC (@sql);

		SET @COLUMN_NAME = '''';
		SET @NewValue = '''';
		SET @OldValue = '''';
		IF @Pos = 0
		BEGIN
			SET @modifiedColumnsList = '''';
		END;
		ELSE
		BEGIN
			SET @modifiedColumnsList = SUBSTRING(@modifiedColumnsList,
			@Pos + 1,
			LEN(@modifiedColumnsList)
			- @Pos);
		END;
  END;

  DROP TABLE #Inserted;
  DROP TABLE #deleted;
  END;';

	EXECUTE sp_executesql @sqlTrigger1, N'@TableName varchar(50), @PrimaryKeyId varchar(50)',
										@TableName,
										@PrimaryKeyId;

	END;


Как я могу избавиться от этих ошибок?

Что я уже пробовал:

Я пробовал создавать триггеры с помощью этих кодов без использования процедуры. Это прекрасно работает.

Tomas Takac

Распечатайте содержимое @sqlTrigger1 и попробуйте запустить его вручную, это должно дать вам больше информации.

Maciej Los

Попробуйте добавить SET NOCOUNT ON; следом BEGIN а раньше DECLARE И дай мне знать, если это поможет.

0x01AA

В назначенном месте SET @sqlTrigger1 там нет окончательной цитаты для '
FOR INSERT, UPDATE, DELETE
AS
BEGIN
SET NOCOUNT ON;


И я не уверен, что это должно быть на одной линии.

1 Ответов

Рейтинг:
1

CHill60

Я думаю, что это вот этот сегмент

'...
	SELECT @UpdatedBy = @@SERVERNAME;
  	SELECT @RecordPk = @PrimaryKeyId FROM inserted;
	SELECT @RecordPkDelete = @PrimaryKeyId FROM deleted;
...'
Разве так не должно быть
'...	
  	SELECT @UpdatedBy = @@SERVERNAME;
  	SELECT @RecordPk = ' + @PrimaryKeyId + ' FROM inserted;
	SELECT @RecordPkDelete = ' + @PrimaryKeyId + ' FROM deleted;
...'