ORDER placement for trigger in t-sql
-
13-03-2021 - |
题
I'm using Sybase ASE version 16.0.0.1915, (follows t-sql syntax) and trying to create a new trigger. This new trigger emulates another existing trigger, however is slightly modified. It would be a whole lot harder to modify the existing trigger to address both "workflows", so copying into a new trigger with modified details and an order of "2" would be my preferred solution.
I'm reading in the docs, that in order to create a new trigger based on the same action, I need to set the order for the triggers to fire off. If no order is specified, it is assigned order of 0 (first). Docs
So here is my trigger, the existing similar trigger does not have an order set. When I place "ORDER 2" into the create statement (after the name, before "on" in row 1), I keep getting syntax error -131.
I've also tried placing the "ORDER 2" after the table name, before "for", and after "insert", before "as". All producing the same error -131.
So what am I doing wrong? Is there some other problem with this trigger preventing me to use the ORDER clause?
create trigger "DBA"."WKM_autoFillCL143" on
"DBA"."case_checklist" for insert
as
if((select top 1 "inserted"."code" from "inserted") in( '143' ) )
begin
declare @parentRef integer,@desc varchar(255),@desc1 varchar(255),@checkID integer
set @parentRef = (select top 1 "parent_ref" from "inserted")
if(@parentRef <> '0')
begin
set @desc = (select "description" from "case_checklist" where "checklist_id" = @parentRef)
if(@desc is not null)
begin
set @checkID = (select top 1 "checklist_id" from "inserted")
update "WKM_RecordChecklistMapping" set "c143" = @checkID where "c142" = @parentRef
declare @tabid integer
set @tabid = (select top 1 "tab_id" from "WKM_recordChecklistMapping" where "c142" = @parentRef)
set @tabid = (select top 1 "tab_id" from "user_tab2_data" where "tab_id" = @tabid)
if(@tabid is not null)
begin
declare @recProvider varchar(255),@recsRequested varchar(255),@dateFrom "datetime",@dateTo "datetime"
set @recProvider = (select top 1 "Provider_Name" from "user_tab2_data" where "tab_id" = @tabid)
set @recsRequested = (select top 1 "Records_Requested" from "user_tab2_data" where "tab_id" = @tabid)
set @dateFrom = (select top 1 "For_Dates_From" from "user_tab2_data" where "tab_id" = @tabid)
set @dateTo = (select top 1 "Through" from "user_tab2_data" where "tab_id" = @tabid)
set @desc1 = 'Receipt '+@recProvider+' Records? '+@recsRequested+', dates '+"coalesce"(convert(varchar(255),@dateFrom,1),'00/00/00')+' to '+"coalesce"(convert(varchar(255),@dateTo,1),'00/00/00')
set @checkID = (select top 1 "checklist_id" from "inserted")
update "case_checklist" set "description" = @desc1,"staff_assigned" = 'ZKS',"due_date" = ("today"()+7) where "checklist_id" = @checkID
end
end
end
end
解决方案
There are 4x different RDBMS products under the Sybase
name ... Adaptiver Server Enterprise (ASE)
, SQLAnywhere
, IQ
and Advantage
. The 4x products do not share a common SQL language/syntax.
The question references a link for the create trigger
syntax in ASE
.
The sample code in the question appears to also be for ASE
.
However, from the comments we've discovered the OP is actually using the SQLAnywhere
product (version 16.0.0.1915
). And while SQLAnywhere
does provide some half-workable support for ASE's
T-SQL
dialect, it does not include a common syntax for the create trigger
command.
From the comments: OP has located the documentation for SQLAnyhere's
create trigger command.
Using one of the examples from that link (scroll down to find CREATE TRIGGER myTrig
), and modifying OP's current trigger code to match the documentation, I'm thinking OP's looking for something like:
create trigger "DBA"."WKM_autoFillCL143"
after insert order 4 on "DBA"."case_checklist"
REFERENCING NEW AS inserted
FOR EACH STATEMENT
BEGIN
....
NOTES:
- I work primarily on
ASE
, and mySQLAnywhere
experience is rather limited, so OP may need to tweak the above to work correctly inSQLAnywhere
; also ... - OP should review the various options available via
SQLAnywhere's
create trigger
command (eg, should the trigger fire before or after the insert?) - OP will need to review the rest of the current (
ASE/T-SQL
) trigger code to see which parts can be used 'as is' inSQLAnywhere
and which parts will need to be rewritten to matchSQLAnywhere's
syntax - OP will also want to verify
SQLAnywhere's
support for quoted identifiers (ie, does the current use of double-quoted identifiers meetSQLAnywhere's
syntax?)
其他提示
@mustaccio has already answered your question in the comments: place it just before AS
at the top of the trigger.
You have a much bigger problem though. Your trigger does not deal with multi-row inserts. It needs a full rewrite. I hope I've got these joins right, as I don't have your full relational model:
create trigger "DBA"."WKM_autoFillCL143" on
"DBA"."case_checklist" for insert
as
if(not exists(select 1
from inserted i
inner join case_checklist c where c.checklist_id = i.parent_ref
where i.code = '143' and i.parent_ref <> '0' and c.description is not null))
return
update w
set c143 = i.checklist_id
from inserted i
join WKM_RecordChecklistMapping w on w.c142 = i.parent_ref
where i.code = '143' and i.parent_ref <> '0' and c.description is not null
update c
set description =
'Receipt ' + ut.Provider_Name + ' Records? ' + ut.Records_Requested +
', dates ' + coalesce(convert(varchar(255), ut.For_Dates_From, 1), '00/00/00') +
' to ' + coalesce(convert(varchar(255), ut.Through, 1), '00/00/00'),
staff_assigned = 'ZKS',
due_date = (today()+7)
from inserted i
inner join WKM_RecordChecklistMapping w on w.c142 = i.parent_ref
inner join user_tab2_data ut on ut.tab_id = w.tab_id
inner join case_checklist c on c.checklist_id = i.checklist_id
where i.code = '143' and i.parent_ref <> '0' and c.description is not null
Is parent_ref <> '0'
correct? It looks like you actually wanted to write parent_ref is not null
. Either way, I hope this is not an int column that you are comparing to text.