用于保存对审计跟踪表的更改的 SQL 触发器

发布于 2024-10-29 20:38:54 字数 1361 浏览 1 评论 0原文

我开始使用 ADS sql 表触发器来存储对一个特定表所做的更改。想法是这样的:

//-------- sql trigger to store changes on patients table to auditLog Table
//----------------------------------------------------------------------
declare cChanges Char( 5000 );
declare allColumns Cursor ;
declare FieldName Char( 25 );
declare StrSql  Char( 255 );
declare @new cursor as select * from __new;
declare @old cursor as select * from __old; 
open @old; 
fetch @old;
open @new; 
fetch @new;
Set cChanges = '';
Open AllColumns as Select * from system.columns where parent = 'patients';
while fetch allColumns DO
// Try
   FieldName = allColumns.Name;
   StrSql = 'IF @new.'+FieldName
          + '<> @old.'+FieldName
          +' and @old.'+FieldName + '<> [ ] THEN ' 
                       + 'cChanges = Trim( '+cChanges+' ) + @old.'+FieldName
                                   + ' Changed to ' + '@new.'+fieldname
                                   + ' | '+ 'ENDIF ; ' ;
   Execute Immediate StrSql ;
//    Catch ALL
//    End Try;
End While;
if cChanges <> '' THEN
    Insert Into AuditLog ( TableKey, Patient, [table], [user], creation, Changes ) 
         values( @new.patient, @new.patient, [Patietns], User(), Now(), cChanges ) ;
ENDIF;
CLOSE AllColumns;
//--------------------------

上面的触发代码错误报告变量cChanges不存在。

有人可以帮忙吗?

雷纳尔多.

I started on an ADS sql table trigger to store changes done on one particular table. Here is the idea:

//-------- sql trigger to store changes on patients table to auditLog Table
//----------------------------------------------------------------------
declare cChanges Char( 5000 );
declare allColumns Cursor ;
declare FieldName Char( 25 );
declare StrSql  Char( 255 );
declare @new cursor as select * from __new;
declare @old cursor as select * from __old; 
open @old; 
fetch @old;
open @new; 
fetch @new;
Set cChanges = '';
Open AllColumns as Select * from system.columns where parent = 'patients';
while fetch allColumns DO
// Try
   FieldName = allColumns.Name;
   StrSql = 'IF @new.'+FieldName
          + '<> @old.'+FieldName
          +' and @old.'+FieldName + '<> [ ] THEN ' 
                       + 'cChanges = Trim( '+cChanges+' ) + @old.'+FieldName
                                   + ' Changed to ' + '@new.'+fieldname
                                   + ' | '+ 'ENDIF ; ' ;
   Execute Immediate StrSql ;
//    Catch ALL
//    End Try;
End While;
if cChanges <> '' THEN
    Insert Into AuditLog ( TableKey, Patient, [table], [user], creation, Changes ) 
         values( @new.patient, @new.patient, [Patietns], User(), Now(), cChanges ) ;
ENDIF;
CLOSE AllColumns;
//--------------------------

The above trigger code errors with reporting variable cChanges does not exists.

Can someone help?

Reinaldo.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

负佳期 2024-11-05 20:38:54

问题确实是您无法访问立即执行的脚本中的局部变量。解决这个问题的方法是使用临时表:

//-------- sql trigger to store changes on patients table to auditLog Table
//----------------------------------------------------------------------
declare cChanges Char( 5000 );
declare allColumns Cursor ;
declare FieldName Char( 25 );
declare StrSql  Char( 255 );
Set cChanges = '';
Open AllColumns as Select * from system.columns where parent = 'patients';
while fetch allColumns DO
// Try
   FieldName = allColumns.Name;

   StrSql = 'SELECT n.FieldName newVal,'
            + 'o.FieldName oldVal '
            + 'INTO #MyTrigTable '
            + 'FROM __new n, __old o';

   EXECUTE IMMEDIATE strSQL;

   IF ( SELECT oldVal FROM #myTrigTable ) <> '' THEN
      IF ( SELECT newVal FROM #myTrigTable ) <> ( SELECT oldVal FROM #myTrigTable ) THEN
         cChanges = 'Construct_SomeThing_Using_#myTrigTable_or_a_cursorBasedOn#MyTrigTable';
         INSERT INTO AuditLog ( TableKey, Patient, [table], [user], creation, Changes ) 
         SELECT patient, patient, 'Patietns', User(), Now(), cChages FROM __new ;
      END;
   END;
   DROP TABLE #myTrigTable;
//    Catch ALL
//    End Try;
End While;
CLOSE AllColumns;
//--------------------------

The problem is indeed that you cannot access local variables in the scripted executed immediately. What you can do to get around the problem is to use temporary table:

//-------- sql trigger to store changes on patients table to auditLog Table
//----------------------------------------------------------------------
declare cChanges Char( 5000 );
declare allColumns Cursor ;
declare FieldName Char( 25 );
declare StrSql  Char( 255 );
Set cChanges = '';
Open AllColumns as Select * from system.columns where parent = 'patients';
while fetch allColumns DO
// Try
   FieldName = allColumns.Name;

   StrSql = 'SELECT n.FieldName newVal,'
            + 'o.FieldName oldVal '
            + 'INTO #MyTrigTable '
            + 'FROM __new n, __old o';

   EXECUTE IMMEDIATE strSQL;

   IF ( SELECT oldVal FROM #myTrigTable ) <> '' THEN
      IF ( SELECT newVal FROM #myTrigTable ) <> ( SELECT oldVal FROM #myTrigTable ) THEN
         cChanges = 'Construct_SomeThing_Using_#myTrigTable_or_a_cursorBasedOn#MyTrigTable';
         INSERT INTO AuditLog ( TableKey, Patient, [table], [user], creation, Changes ) 
         SELECT patient, patient, 'Patietns', User(), Now(), cChages FROM __new ;
      END;
   END;
   DROP TABLE #myTrigTable;
//    Catch ALL
//    End Try;
End While;
CLOSE AllColumns;
//--------------------------
飘落散花 2024-11-05 20:38:54

我相信问题与您的动态 SQl 尝试设置触发器主体中声明的值有关。

例如,您的 cChanges = TRIM( 语句可能会导致问题,因为 cChanges 不存在该上下文。

您应该使用绑定变量来完成此操作,而不是尝试使用 = 符号进行设置。

您可以在其中看到他们说您无法通过访问

http 直接访问这些变量://devzone.advantagedatabase.com/dz/webhelp/advantage9.1/advantage_sql/sql_psm_脚本/execute_immediate.htm

I believe the problem has to do with your dynamic SQl attempting to set a value declared in your trigger body.

e.g. Your cChanges = TRIM( statement might be causing the problem since cChanges does not exist that context.

You should use binding variables to accomplish this instead of attempting to set using the = sign.

You can see in their docs they say you cannot access those variables directly by going to

http://devzone.advantagedatabase.com/dz/webhelp/advantage9.1/advantage_sql/sql_psm_script/execute_immediate.htm

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文