旧话重提,有人能解决吗?(在程序中创建自定义SQL语句跟踪过程 ) ( 积分: 300 )

  • 主题发起人 主题发起人 Jiao_he
  • 开始时间 开始时间
J

Jiao_he

Unregistered / Unconfirmed
GUEST, unregistred user!
***把原问题重新整理下,原贴内容请看:http://www.delphibbs.com/delphibbs/dispq.asp?lid=3175366
***如果下面的问题解决了,用于程序的数据库同步和解决关于系统数据更新的日志记录不失为一个好方法,所以希望大家共同解决。
***原来的BCB语句已由chenybin译成Delphi语句了,下面是整理后的Delphi语句,但由于里面提及的SQL系统储存过程是SQL Server 7.0版本的,在SQL Server 2000中已更换了,名称是参数设置都不一样了。
使用存储过程定义自己的跟踪: (在SQL帮助中的描述)
1、使用 sp_trace_setevent 指定要捕获的事件。
2、指定任何事件筛选。有关更多信息,请参见如何设置跟踪筛选 (Transact-SQL)。
3、使用 sp_trace_create 为捕获的事件数据指定目的。


整理后的问题如下:
Sql Server做为一种数据库管理系统,它与客户的接口都是通过SQL语句进行的, 用户在插入一条记录时,SQL Server会接收到Insert语句;更改一条记录时,会接收到 Update命令...
那么如果我们能在SQL Server中跟踪到所有发给SQL Server的SQL语句,那么我们就可以知道数据库发生了哪些改变,并可以将这种改变发给另外一到服务器,从而实现数据实时同步的功能.
值得高兴的是,SQL Server 提供了跟踪功能 ,它们是以 xp_trace_XXXXXX的一系列存储过程,你可以设置过滤条件,从而只跟踪影响你的数据库 变化的SQL 语句,将这些SQL 语句存放在本地表中,再从本地表中读出,发送给另外一台服务器 ,从而实现数据同步功能. 这种方法可以跟踪任何类型的变化,包括Image类型数据的改变.

以下面是用实现建立跟踪过程:
/* 功能: 在SQL Server中建立跟踪
输入参数: DBID - 想要跟踪的数据库的ID号,可以用数据库名在 master.dbosysdatabases中查出。
AppFilter - 限制跟踪哪个客户端应用程序提交给SQL Server的SQL语句
SQLFilter - 限制跟踪哪类的SQL 语句,可以控制只跟踪UPDATE,INSERT,DELETE 语句
DstTable - 将跟踪到的信息存储到数据库的哪一个表中
TraceHandle -引用类型变量,返回给调用者建立起的跟踪句柄
返回值: true 成功,false 失败
*/
function TForm1.BuildTrace(DBID: Integer; AppFilter, SQLFilter, DstTable: string; var TraceHandle: Integer): boolean;
var
tempBuf: string;
pSQL : TStrings;
begin
Result := false;
Query1.Close; //Query1 为 TADOQuery的组件
//实验中发现若用BDE中的TQuery组件,对跟踪到的
//Image类型数据会操作时会发生错误.
Query1.SQL.Clear;
pSQL := Query1.SQL;
pSQL.Add('USE master'); //将当前数据库设为master
pSQL.Add('DECLARE @queue_handle int');
pSQL.Add('DECLARE @column_value int');
// 可以跟踪很多种信息,但通常只需要其中一部分, @column_value用来确定需要哪些信息.
//下行每个数字代表一列,具体可参见Transact -SQL Help
pSQL.Add('SET @column_value = 67108864|1|512|1024|10384');
// 加入一个跟踪过程,若成功, @queue_handle将是一个有效的值
pSQL.Add('EXEC xp_trace_addnewqueue 1000,5,95,90,@column_value,@queue_handle OUTPUT');
// 以下句设置跟踪条件
//设置跟踪何种事件, 41为TSQL Complete事件, 还有其它事件,如连接事件等等,
// 但对同步功能来说,只需要TSQL Complete事件.
pSQL.Add('EXEC xp_trace_seteventclassrequired @queue_handle, 41,1 ');
//设置跟踪哪种客户端的发过来的SQL 语句,客户端在向SQL Server发出命令时,都有一个
// Application Name
tempBuf := Format('EXEC xp_trace_setappfilter @queue_handle,''%s'',NULL', [AppFilter]);
pSQL.Add((tempBuf));
// 设置跟踪针对哪个数据库的SQL 语句
tempBuf := Format('EXEC xp_trace_setdbidfilter @queue_handle,%d',[DBID]);
pSQL.Add( (tempBuf));
//设置SQL 语句的过滤条件,可设置成" UPDATE%;DELETE%;INSERT%",则只跟踪UPDATE, INSERT 和 DELETE语句
tempBuf := Format('Exec xp_trace_settextfilter @queue_handle,''%s'',NULL', [SQLFilter]);
pSQL.Add((tempBuf));
//设置将跟踪到的信息存放在哪个表里 ,
//如果表不存在,则自动创建,表的列数由前面的@colomun_value控制.
// 为以后方便读出控制,可以在自动创建了这个表后,手工的为其加上ID字段(自动增长字段),并做为主索引.
tempBuf := Format('EXEC xp_trace_setqueuedestination @queue_handle,4,1,NULL,''%s''', [DstTable]);
pSQL.Add( (tempBuf));
//开始跟踪
pSQL.Add('EXEC xp_trace_startconsumer @queue_handle');
pSQL.Add('SELECT @queue_handle QueueHandle');
// 将批命令提交到SQL SERVER, 执行完毕后,跟踪过程就建立起来了
try
Query1.Open();
except
Exit;
end;
TraceHandle := Query1.FieldByName('QueueHandle').AsInteger;
Result := true;
end;

//调用过程
...
var
TraceHandle,DBID:integer;
begin
DBID = GetDBID('MyDB1'); //根据数据库名从SQL Server的sysdatabases中查询
if ( BuildTrace( DBID,
'MyApp',
'INSERT%;UPDATE%;DELETE%',
'MyDB1.dbo.MyTrace',
TraceHandle)=True
then
Application.MessageBox("跟踪过程已被建立","提示",MB_OK)
else
Application.MessageBox("跟踪过程建立失败","提示",MB_OK);
end;

现在主要解决的是在SQL Server200中的
xp_trace_addnewqueue
xp_trace_seteventclassrequired
xp_trace_setappfilter
xp_trace_setdbidfilter
xp_trace_settextfilter
xp_trace_setqueuedestination
xp_trace_startconsumer
已不使用了,已经由
sp_trace_setevent
sp_trace_setfilter
sp_trace_create
简化代替了,参数设置也不一样,所以在上述使用中已有很大差别。
请熟SQL数据库的朋友帮忙;也可以参考SQL里面的帮助看看。
 
***把原问题重新整理下,原贴内容请看:http://www.delphibbs.com/delphibbs/dispq.asp?lid=3175366
***如果下面的问题解决了,用于程序的数据库同步和解决关于系统数据更新的日志记录不失为一个好方法,所以希望大家共同解决。
***原来的BCB语句已由chenybin译成Delphi语句了,下面是整理后的Delphi语句,但由于里面提及的SQL系统储存过程是SQL Server 7.0版本的,在SQL Server 2000中已更换了,名称是参数设置都不一样了。
使用存储过程定义自己的跟踪: (在SQL帮助中的描述)
1、使用 sp_trace_setevent 指定要捕获的事件。
2、指定任何事件筛选。有关更多信息,请参见如何设置跟踪筛选 (Transact-SQL)。
3、使用 sp_trace_create 为捕获的事件数据指定目的。


整理后的问题如下:
Sql Server做为一种数据库管理系统,它与客户的接口都是通过SQL语句进行的, 用户在插入一条记录时,SQL Server会接收到Insert语句;更改一条记录时,会接收到 Update命令...
那么如果我们能在SQL Server中跟踪到所有发给SQL Server的SQL语句,那么我们就可以知道数据库发生了哪些改变,并可以将这种改变发给另外一到服务器,从而实现数据实时同步的功能.
值得高兴的是,SQL Server 提供了跟踪功能 ,它们是以 xp_trace_XXXXXX的一系列存储过程,你可以设置过滤条件,从而只跟踪影响你的数据库 变化的SQL 语句,将这些SQL 语句存放在本地表中,再从本地表中读出,发送给另外一台服务器 ,从而实现数据同步功能. 这种方法可以跟踪任何类型的变化,包括Image类型数据的改变.

以下面是用实现建立跟踪过程:
/* 功能: 在SQL Server中建立跟踪
输入参数: DBID - 想要跟踪的数据库的ID号,可以用数据库名在 master.dbosysdatabases中查出。
AppFilter - 限制跟踪哪个客户端应用程序提交给SQL Server的SQL语句
SQLFilter - 限制跟踪哪类的SQL 语句,可以控制只跟踪UPDATE,INSERT,DELETE 语句
DstTable - 将跟踪到的信息存储到数据库的哪一个表中
TraceHandle -引用类型变量,返回给调用者建立起的跟踪句柄
返回值: true 成功,false 失败
*/
function TForm1.BuildTrace(DBID: Integer; AppFilter, SQLFilter, DstTable: string; var TraceHandle: Integer): boolean;
var
tempBuf: string;
pSQL : TStrings;
begin
Result := false;
Query1.Close; //Query1 为 TADOQuery的组件
//实验中发现若用BDE中的TQuery组件,对跟踪到的
//Image类型数据会操作时会发生错误.
Query1.SQL.Clear;
pSQL := Query1.SQL;
pSQL.Add('USE master'); //将当前数据库设为master
pSQL.Add('DECLARE @queue_handle int');
pSQL.Add('DECLARE @column_value int');
// 可以跟踪很多种信息,但通常只需要其中一部分, @column_value用来确定需要哪些信息.
//下行每个数字代表一列,具体可参见Transact -SQL Help
pSQL.Add('SET @column_value = 67108864|1|512|1024|10384');
// 加入一个跟踪过程,若成功, @queue_handle将是一个有效的值
pSQL.Add('EXEC xp_trace_addnewqueue 1000,5,95,90,@column_value,@queue_handle OUTPUT');
// 以下句设置跟踪条件
//设置跟踪何种事件, 41为TSQL Complete事件, 还有其它事件,如连接事件等等,
// 但对同步功能来说,只需要TSQL Complete事件.
pSQL.Add('EXEC xp_trace_seteventclassrequired @queue_handle, 41,1 ');
//设置跟踪哪种客户端的发过来的SQL 语句,客户端在向SQL Server发出命令时,都有一个
// Application Name
tempBuf := Format('EXEC xp_trace_setappfilter @queue_handle,''%s'',NULL', [AppFilter]);
pSQL.Add((tempBuf));
// 设置跟踪针对哪个数据库的SQL 语句
tempBuf := Format('EXEC xp_trace_setdbidfilter @queue_handle,%d',[DBID]);
pSQL.Add( (tempBuf));
//设置SQL 语句的过滤条件,可设置成" UPDATE%;DELETE%;INSERT%",则只跟踪UPDATE, INSERT 和 DELETE语句
tempBuf := Format('Exec xp_trace_settextfilter @queue_handle,''%s'',NULL', [SQLFilter]);
pSQL.Add((tempBuf));
//设置将跟踪到的信息存放在哪个表里 ,
//如果表不存在,则自动创建,表的列数由前面的@colomun_value控制.
// 为以后方便读出控制,可以在自动创建了这个表后,手工的为其加上ID字段(自动增长字段),并做为主索引.
tempBuf := Format('EXEC xp_trace_setqueuedestination @queue_handle,4,1,NULL,''%s''', [DstTable]);
pSQL.Add( (tempBuf));
//开始跟踪
pSQL.Add('EXEC xp_trace_startconsumer @queue_handle');
pSQL.Add('SELECT @queue_handle QueueHandle');
// 将批命令提交到SQL SERVER, 执行完毕后,跟踪过程就建立起来了
try
Query1.Open();
except
Exit;
end;
TraceHandle := Query1.FieldByName('QueueHandle').AsInteger;
Result := true;
end;

//调用过程
...
var
TraceHandle,DBID:integer;
begin
DBID = GetDBID('MyDB1'); //根据数据库名从SQL Server的sysdatabases中查询
if ( BuildTrace( DBID,
'MyApp',
'INSERT%;UPDATE%;DELETE%',
'MyDB1.dbo.MyTrace',
TraceHandle)=True
then
Application.MessageBox("跟踪过程已被建立","提示",MB_OK)
else
Application.MessageBox("跟踪过程建立失败","提示",MB_OK);
end;

现在主要解决的是在SQL Server200中的
xp_trace_addnewqueue
xp_trace_seteventclassrequired
xp_trace_setappfilter
xp_trace_setdbidfilter
xp_trace_settextfilter
xp_trace_setqueuedestination
xp_trace_startconsumer
已不使用了,已经由
sp_trace_setevent
sp_trace_setfilter
sp_trace_create
简化代替了,参数设置也不一样,所以在上述使用中已有很大差别。
请熟SQL数据库的朋友帮忙;也可以参考SQL里面的帮助看看。
 
天呀,为什么路过的都不说话呀?
 
你这么守信用,我一定尽力帮你回答
 
大概看了一下以上的代码:如果你确定是由下面三个过程代替了,可以详细查看一下三个过程的处理方法,再对应修改程序代码来调用这三个过程啊,我想存储过程的参数变化不是太大吧:

sp_trace_setevent
sp_trace_setfilter
sp_trace_create
 
不,变化挺大的,而且变化后的参数没有上述提到的属性,所以不知道如何用,我研究了好长时间了还是看不懂。
 
对应替代关系是
sp_trace_setevent
xp_trace_addnewqueue
xp_trace_eventclassrequired
xp_trace_seteventclassrequired


sp_trace_setfilter
xp_trace_setappfilter
xp_trace_settextfilter

sp_trace_create
xp_trace_setqueuedestination


sp_trace_setstatus
xp_trace_startconsumer

空了再看具体这么替换
 
我找了一段代码,大概意思差不多了,可以输入DBID,AppFilter和最后面的两个参数,只偶SQLFilter的。 蓝色的部分还没搞很清楚,蓝色的部分是表示跟踪什么语句,另外我在最后面写上这么得到这些代码

declare @rc int
declare @TraceID int
declare @maxfilesize bigint
declare @DateTime datetime

set @DateTime = '2005-08-27 20:33:16.000'--终止日期
set @maxfilesize = 5 -- 文件最大值

exec @rc = sp_trace_create @TraceID output, 0, N'保存日至的文件名', @maxfilesize, @Datetime

-- Set the events
[blue]declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 46, 1, @on
exec sp_trace_setevent @TraceID, 46, 6, @on
exec sp_trace_setevent @TraceID, 46, 9, @on
exec sp_trace_setevent @TraceID, 46, 10, @on
exec sp_trace_setevent @TraceID, 46, 11, @on
exec sp_trace_setevent @TraceID, 46, 12, @on
exec sp_trace_setevent @TraceID, 46, 13, @on
exec sp_trace_setevent @TraceID, 46, 14, @on
exec sp_trace_setevent @TraceID, 46, 16, @on
exec sp_trace_setevent @TraceID, 46, 17, @on
exec sp_trace_setevent @TraceID, 46, 18, @on
exec sp_trace_setevent @TraceID, 47, 1, @on
exec sp_trace_setevent @TraceID, 47, 6, @on
exec sp_trace_setevent @TraceID, 47, 9, @on
exec sp_trace_setevent @TraceID, 47, 10, @on
exec sp_trace_setevent @TraceID, 47, 11, @on
exec sp_trace_setevent @TraceID, 47, 12, @on
exec sp_trace_setevent @TraceID, 47, 13, @on
exec sp_trace_setevent @TraceID, 47, 14, @on
exec sp_trace_setevent @TraceID, 47, 16, @on
exec sp_trace_setevent @TraceID, 47, 17, @on
exec sp_trace_setevent @TraceID, 47, 18, @on
exec sp_trace_setevent @TraceID, 48, 1, @on
exec sp_trace_setevent @TraceID, 48, 6, @on
exec sp_trace_setevent @TraceID, 48, 9, @on
exec sp_trace_setevent @TraceID, 48, 10, @on
exec sp_trace_setevent @TraceID, 48, 11, @on
exec sp_trace_setevent @TraceID, 48, 12, @on
exec sp_trace_setevent @TraceID, 48, 13, @on
exec sp_trace_setevent @TraceID, 48, 14, @on
exec sp_trace_setevent @TraceID, 48, 16, @on
exec sp_trace_setevent @TraceID, 48, 17, @on
exec sp_trace_setevent @TraceID, 48, 18, @on
exec sp_trace_setevent @TraceID, 49, 1, @on
exec sp_trace_setevent @TraceID, 49, 6, @on
exec sp_trace_setevent @TraceID, 49, 9, @on
exec sp_trace_setevent @TraceID, 49, 10, @on
exec sp_trace_setevent @TraceID, 49, 11, @on
exec sp_trace_setevent @TraceID, 49, 12, @on
exec sp_trace_setevent @TraceID, 49, 13, @on
exec sp_trace_setevent @TraceID, 49, 14, @on
exec sp_trace_setevent @TraceID, 49, 16, @on
exec sp_trace_setevent @TraceID, 49, 17, @on
exec sp_trace_setevent @TraceID, 49, 18, @on[/blue]


---- 设定Filter
declare @intfilter int
set @intfilter = 10061-- 你的DBID
exec sp_trace_setfilter @TraceID, 3, 1, 0, @intfilter
exec sp_trace_setfilter @TraceID, 10, 1, 6, N'Mysql'-- 你的AppFilter
exec sp_trace_setstatus @TraceID, 1
select TraceID=@TraceID

打开企业管理器,找到对应的数据,然后在菜单找到工具,SQL 事件探查器,然后是新建跟踪,在常规那个标签可以设置对应的保存记录用的表名,在事件标签下面的事件类选中对象,就可以看到需要跟踪的那些SQL语句了,下面有说明的,最后到筛选列,可以看到ApplicationName和DataBaseID,这两个准则,然后点击运行在菜单文件找到脚本跟踪,选择用于SQL SERVER 2000就可以了,会把脚本保存出来,希望对你有用,如果解决了请结的把解决办法放上来
 
先谢谢chenybin了。

弄了半天还是郁闷呀,探测器中基本弄懂了,但是
当把探测器中的跟踪导出到SQL 2000脚本时,却提示不支持通过SP's写入表( -- Writing to a table is not supported through the SP's )(请看下面生成的红色英文注释,??奇怪这为什么无法显示颜色)
而导出到SQL 7.0的脚本则无此注释,还能生成表名,难道高版本的功能还比低版差吗?
还是有什么还没弄清楚?真郁闷呀!!!

***以下是生成的2000脚本
-- Create a Queue
declare @rc int
declare @TraceID int
declare @maxfilesize bigint
declare @DateTime datetime

set @DateTime = '2005-08-28 06:37:51.000'
set @maxfilesize = 5

-- Please replace the text InsertFileNameHere, with an appropriate
-- filename prefixed by a path, e.g., c:/MyFolder/MyTrace. The .trc extension
-- will be appended to the filename automatically. If you are writing from
-- remote server to local drive, please use UNC path and make sure server has
-- write access to your network share

exec @rc = sp_trace_create @TraceID output, 0, N'InsertFileNameHere', @maxfilesize, @Datetime
if (@rc != 0) goto error

-- Client side File and Table cannot be scripted

[red]-- Writing to a table is not supported through the SP's [/red]

-- Set the events
declare @on bit
set @on = 1
exec sp_trace_setevent @TraceID, 10, 1, @on
exec sp_trace_setevent @TraceID, 10, 9, @on
exec sp_trace_setevent @TraceID, 10, 10, @on
exec sp_trace_setevent @TraceID, 10, 11, @on
exec sp_trace_setevent @TraceID, 10, 12, @on
exec sp_trace_setevent @TraceID, 10, 14, @on


-- Set the Filters
declare @intfilter int
declare @bigintfilter bigint

set @intfilter = 7
exec sp_trace_setfilter @TraceID, 3, 1, 0, @intfilter

exec sp_trace_setfilter @TraceID, 10, 0, 7, N'SQL Profiler'


-- Set the trace status to start
exec sp_trace_setstatus @TraceID, 1

-- display trace id for future references
select TraceID=@TraceID
goto finish

error:
select ErrorCode=@rc

finish:
go

***以下是生成7.0的脚本(test1是生成的表)
-- Create a Queue
declare @rc int
declare @QueueHandle int
exec @rc = xp_trace_addnewqueue 1000, 5000, 95, 90, 100665349, @QueueHandle output
if (@rc != 0) goto error

-- Set the events
-- SQL Server 2000 specific events will not be scripted

exec xp_trace_seteventclassrequired @QueueHandle, 10, 1


-- Set the Filters
exec xp_trace_setdbidfilter @QueueHandle, 7


-- set the destinations
exec xp_trace_setqueuedestination @QueueHandle, 4, 1, N'it-he',N'[master]..[Test1]'

-- start the consumers
exec xp_trace_startconsumer @QueueHandle


-- save the definition in the registry
exec xp_trace_savequeuedefinition @QueueHandle, N'Test1', 1

-- display queue handle for future references
select QueueHandle=@QueueHandle
goto finish

error:
select ErrorCode=@rc

finish:
go
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=16458
KeyLife富翁笔记
作者?: 时报平
标题?: 在SQLServer2000中如何单步调试存储过程
看看这个有没有有些帮助吧
 
没找到什么有价值的帖子,SP估计就是存储过程吧,瞎猜的,这个倒不是关键问题,我们存文件也没关系,但是就是搞不明白怎么捕获对应的那些语句,其实大部分算达到功能了,楼主好运吧[:D]

http://www.588188.com/netbook/sqlserver2000/profiler/


颜色是你需要进入另外一种风格才可以显示的,就时候黄色界面那种
 
不错,有价值!
 
高手啊,期待ing。。。。。。
 

Similar threads

后退
顶部