October 20, 2005 at 2:55 pm
All of this is part of a string that gets executed using EXEC().
(so yes, those are 2 quotes, and that's correct)
If the column "edituser" exists, i want to collect its value
if (Select Coalesce(Col_length(''inserted'',''edituser''),0)) > 0
begin
set @UserName = (select top 1 edituser from inserted)
end
I believe what's happening is that when the string is passed to the exec statement, it is checking the validity of the statement within the IF statement, and failing. It seems like I've read something about this before, but I'm having trouble finding it. Thanks in advanced for any replies
October 20, 2005 at 3:03 pm
Is this the "inserted" table as in you're doing this in a trigger?
If so, I am not aware that EXEC will allow you to reference the inserted table: the EXEC happens outside of that context.
October 20, 2005 at 3:05 pm
John is correct there is not direct access to the inserted table from dynamic SQL. Which you shouldn't be using anyways on a trigger
* Noel
October 20, 2005 at 3:07 pm
Yes, I am creating the trigger. So the EXEC is around the whole CREATE TRIGGER statement. I have an auditing trigger I use to audit column changes, and I'm trying to script it so that it will script out to all the user tables in the DB, otherwise I'm stuck applying the triggers manually to the tables.
October 20, 2005 at 3:18 pm
There is nothing wrong in having a code generator for the triggers. The bad part is to use dynamic sql in the generated code!
* Noel
October 20, 2005 at 3:30 pm
Agreed. Any help with the original ? then?
October 20, 2005 at 4:04 pm
Again, an IF statement in a CREATE TRIGGER statement is failing. The entire CREATE TRIGGER statement is being created/executed using EXEC. I believe the reason for failing is that within the IF statement a SELECT statement refers to a column that the IF statement is testing for the existance of (see original post).
October 20, 2005 at 4:21 pm
Please post the whole code so we know what we're working with.
October 20, 2005 at 4:32 pm
Here it is. I circumvented it by checking the table structure while creating the trigger and now it works fine. The audit trigger is one I found online @ http://www.nigelrivett.net/AuditTrailTrigger.html and modified to suit my needs. Thanks to those who helped.
declare @tables table (tablename varchar(50))
declare @table varchar(50)
declare @trigger char (5000)
insert into @tables
select table_name from information_schema.tables
where not (substring(table_name,1,3)= 'sys' or substring(table_name,1,3)= 'dtp'
or table_type = 'view')
while (select count(*) from @tables) > 0
begin
set @table = (select top 1 tablename from @tables order by tablename)
--process to be run on each table goes here
if @table 'Audit'
begin
set @trigger =
'create trigger tr_Audit_' + @table + ' on ' + @table + ' for update
as
declare @bit int ,
@field int ,
@maxfield int ,
@char int ,
@fieldname varchar(128) ,
@TableName varchar(128) ,
@PKCols varchar(1000) ,
@sql varchar(2000),
@UpdateDate varchar(21) ,
@UserName varchar(128) ,
@Type char(1) ,
@PKSelect varchar(1000)
select @TableName = (SELECT Object_name(parent_obj) AS TableName from dbo.SysObjects WHERE id = @@procid)
-- date and user
select @UserName = system_user ,
@UpdateDate = convert(varchar(8), getdate(), 112) + '' '' + convert(varchar(12), getdate(), 114)'
if (Select Coalesce(Col_length(@table,'edituser'),0)) > 0
begin
set @trigger = rtrim(@trigger) + ' set @UserName = (select top 1 edituser from inserted)'
end
set @trigger = rtrim(@trigger) + '
-- Action
/********************************************************
This section commented out because we only use this
trigger for updates
if exists (select * from inserted)
if exists (select * from deleted)
select @Type = ''U''
else
select @Type = ''I''
else
select @Type = ''D''
Next line removed along w/comments to audit all changes*/
select @type = ''U''
-- get list of columns
select * into #ins from inserted
select * into #del from deleted
-- Get primary key columns for full outer join
select@PKCols = coalesce(@PKCols + '' and'', '' on'') + '' i.'' + c.COLUMN_NAME + '' = d.'' + c.COLUMN_NAME
fromINFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
where pk.TABLE_NAME = @TableName
andCONSTRAINT_TYPE = ''PRIMARY KEY''
andc.TABLE_NAME = pk.TABLE_NAME
andc.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
-- Get primary key select for insert
select @PKSelect = coalesce(@PKSelect+''+'','''') + '''''''' + ''''''+convert(varchar(100),coalesce(i.'' + COLUMN_NAME +'',d.'' + COLUMN_NAME + ''))+''''''''''
fromINFORMATION_SCHEMA.TABLE_CONSTRAINTS pk ,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE c
where pk.TABLE_NAME = @TableName
andCONSTRAINT_TYPE = ''PRIMARY KEY''
andc.TABLE_NAME = pk.TABLE_NAME
andc.CONSTRAINT_NAME = pk.CONSTRAINT_NAME
if @PKCols is null
begin
raiserror(''no PK on table %s'', 16, -1, @TableName)
return
end
select @field = 0, @maxfield = max(ORDINAL_POSITION) from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName
while @field @field
select @bit = (@field - 1 )% 8 + 1
select @bit = power(2,@bit - 1)
select @char = ((@field - 1) / 8) + 1
if substring(COLUMNS_UPDATED(),@char, 1) & @bit > 0 or @Type in (''I'',''D'')
begin
select @fieldname = COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = @TableName and ORDINAL_POSITION = @field
select @sql = ''insert Audit (Type, TableName, PK, FieldName, OldValue, NewValue, UpdateDate, UserName)''
select @sql = @sql + '' select '''''' + @Type + ''''''''
select @sql = @sql + '','''''' + @TableName + ''''''''
select @sql = @sql + '','' + @PKSelect
select @sql = @sql + '','''''' + @fieldname + ''''''''
select @sql = @sql + '',convert(varchar(1000),d.'' + @fieldname + '')''
select @sql = @sql + '',convert(varchar(1000),i.'' + @fieldname + '')''
select @sql = @sql + '','''''' + @UpdateDate + ''''''''
select @sql = @sql + '','''''' + @UserName + ''''''''
select @sql = @sql + '' from #ins i full outer join #del d''
select @sql = @sql + '' where i.'' + @fieldname + '' d.'' + @fieldname
select @sql = @sql + '' or (i.'' + @fieldname + '' is null and d.'' + @fieldname + '' is not null)''
select @sql = @sql + '' or (i.'' + @fieldname + '' is not null and d.'' + @fieldname + '' is null)''
exec(@sql)
end
end
'
print @trigger
exec(@trigger)
--
end
--end process, delete tablename from variable
delete from @tables where (tablename = @table)
end
Viewing 9 posts - 1 through 8 (of 8 total)
You must be logged in to reply to this topic. Login to reply