현재 트리거는 다음과 같습니다.
CREATE TRIGGER TestTrigger
ON DATABASE
FOR ALTER_TABLE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @FULL_STATEMENT SYSNAME
SELECT @FULL_STATEMENT = EVENTDATA().value('(/EVENT_INSTANCE/TSQLCommand/CommandText)[1]','nvarchar(max)')
print('The following SQL statement was executed:')
print('')
print (@FULL_STATEMENT)
print('')
print('Next step is to work out how to single out the added column name')
ROLLBACK
END
그런 다음 다음 SQL 문을 실행합니다.
USE [a_Database]
ALTER TABLE dbo.TABLE
ADD TestColumn varchar(50)
그리고 다음을 출력합니다.
다음 SQL 문이 실행되었습니다.
ALTER TABLE dbo.TABLE
TestColumn varchar (50) 추가
다음 단계는 추가 된 열 이름을 구분하는 방법을 찾는 것입니다.
메시지 3609, 수준 16, 상태 2, 줄 2
트랜잭션이 트리거에서 종료되었습니다. 배치가 중단되었습니다.
최종 목표는 "TestColumn"을 골라내어 내부 프로그램을 손상시킬 수있는 특정 문자를 포함하지 않도록하는 것입니다. 예를 들어 "TestColumn"은 유효한 이름이지만 "Test.Column"은 그렇지 않습니다.
원치 않는 문자를 확인하기 위해 골라 내고 새 변수 ( "@ColumnName"?)에 전달하는 가장 좋은 방법은 무엇입니까?
alter 문은 둘 이상의 열을 추가 할 수 있다는 점을 명심해야합니다. alter column 문에 대해 생성 된 XML을 보면 더 나은 아이디어를 얻을 수 있습니다.
ALTER TABLE dbo.EventTest ADD NewColumn1 INT, NewColumn2 INT;
----------------------------
<EVENT_INSTANCE>
<EventType>ALTER_TABLE</EventType>
<PostTime>2015-06-30T14:28:30.790</PostTime>
<SPID>67</SPID>
<ServerName>XXXXXX</ServerName>
<LoginName>XXXXXX</LoginName>
<UserName>dbo</UserName>
<DatabaseName>XXXXXX</DatabaseName>
<SchemaName>dbo</SchemaName>
<ObjectName>EventTest</ObjectName>
<ObjectType>TABLE</ObjectType>
<AlterTableActionList>
<Create>
<Columns>
<Name>NewColumn1</Name>
<Name>NewColumn2</Name>
</Columns>
</Create>
</AlterTableActionList>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
<CommandText>ALTER TABLE dbo.EventTest ADD NewColumn1 INT, NewColumn1 INT;</CommandText>
</TSQLCommand>
</EVENT_INSTANCE>
따라서 여러 열을 추가 할 수 있으므로 사용할 수있는 열 목록을 얻으려면 여러 열을 확인해야합니다.
SELECT ColumnName = Cols.value('.', 'SYSNAME')
FROM EVENTDATA().nodes('EVENT_INSTANCE/AlterTableActionList/Create/Columns') x (Cols);
그런 다음 EXISTS
예약 된 이름 목록 등을 확인하고 원하지 않는 문자를 확인하는 데 사용할 수 있습니다.
IF EXISTS
( SELECT 1
FROM ( SELECT ColumnName = Cols.value('.', 'SYSNAME')
FROM EVENTDATA().nodes('EVENT_INSTANCE/AlterTableActionList/Create/Columns') x (Cols)
) AS t
WHERE PATINDEX('%[.@!-]%', t.ColumnName) > 0 -- USE PATTERN MATCH TO CHECK FOR UNWANTED CHARACTERS
OR EXISTS
( SELECT 1
FROM dbo.ReservedColumnNames AS rc
WHERE rc.Name = t.ColumnName
)
)
BEGIN
RAISERROR(...)
ROLLBACK;
END
고려해야 할 또 다른 사항은 sp_rename
다른 이벤트를 발생시키는 것이며 아마도 이것을 추적하고 싶을 것입니다. 여기 XML은 다음과 같습니다.
<EVENT_INSTANCE>
<EventType>RENAME</EventType>
....
<SchemaName>dbo</SchemaName>
<ObjectName>NewColumn</ObjectName>
<ObjectType>COLUMN</ObjectType>
<TargetObjectName>EventTest</TargetObjectName>
<TargetObjectType>TABLE</TargetObjectType>
<NewObjectName>NewColumn2</NewObjectName>
<Parameters>
<Param>dbo.EventTest.NewColumn</Param>
<Param>NewColumn2</Param>
<Param>COLUMN</Param>
</Parameters>
<TSQLCommand>
<SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE" />
<CommandText>EXECUTE SP_RENAME 'dbo.EventTest.NewColumn', 'NewColumn2', 'COLUMN';</CommandText>
</TSQLCommand>
</EVENT_INSTANCE>
따라서 여기서는 한 번에 하나의 열만 될 수 있으므로 약간 다르게 추적해야합니다. 노드에 대해 걱정할 필요가 없습니다.
SELECT EVENTDATA().value('EVENT_INSTANCE[1]/NewObjectName[1]', 'SYSNAME')
WHERE EVENTDATA().value('EVENT_INSTANCE[1]/EventType[1]', 'VARCHAR(13)') = 'RENAME'
AND EVENTDATA().value('EVENT_INSTANCE[1]/ObjectType[1]', 'VARCHAR(13)') = 'COLUMN';
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다