T-SQL经验总结

本文总结了T-SQL中变量声明、使用table数据类型、表值函数等实用技巧,并提供了轻量级数据库备份及恢复的实际案例,包括动态SQL执行与bcp命令的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

又很久没有写 T-SQL了(以前做sp的时候产品开发都是用T-SQL来做)
         最近做一个项目,其中有个需求要求轻量级备份数据库数据,结果备受T-SQL折磨。后悔以前写T-SQL的时候不总结经验,项目开发的时候要到处找资料。
        现在将一些自以为有用的T-SQL总结总结,以免以后要用的时候又到处找
一、声明的变量,不赋值的时候默认都为NULL
例:DECLARE  @iIndex     int
        DECLARE  @nvchString nvarchar(400)
 
       在做字符串联的时候   NULL+任何字符串   结果都为NULL
       在做整数相乘的时候 NULL*任何整数       结果都为NULL
      所以最好是在声明的变量的时候给它赋初始i值
二、用table 数据类型代替游标可以减少死锁的机会
      table 数据类型的使用请参考T-SQL的帮助(输入"table 数据类型" 即可找到)
     下面举个例子说明table数据类型的使用:(1)声明一个表类型变量@table,有两个列,一个是自增的id列       (2)增加一条记录到表变量里(3)查看表变量的数据记录
DECLARE @table TABLE 
 (
   id   
int identity(1,1),
   name 
nvarchar(20)
 )
 
 
insert into @table
 (
 name
 )
 
values
 (
 
'eric_cheung'
 )
 
 
select * from @table

 

三、表值函数
主要利用表值函数来存储全局的信息。(见综合例子)
四、执行bcp和DOC命令
主要是用 master..xp_cmdshell 来执行。(见综合例子)
五、动态SQL
主要是用 master..sp_executesql 来执行动态SQL。(见综合例子)
六、综合例子。
下面给出一个T-SQL的综合例子。
注意:此综合例子是项目开发中写的存储过程和函数,要有项目上下文环境,所以代码复制未必可以运行通过。
1、定义一个表值函数

CREATE        FUNCTION tableList ()
 
RETURNS @retTableList 
 
TABLE (id int identity(1,1NOT NULL ,
    table_name 
nvarchar(64NOT NULL,
    isLog 
int,--0表示非日志,1表示日志
    type int--1表示有时间,2表示没有时间
    
  
/*Returns a result set that lists all the employees who report to given 
 employee directly or indirectly.
*/

 
AS
 
BEGIN
 
  
 
INSERT @retTableList(isLog,table_name,type) values(0,'tbl_ftp',1)
 
 
INSERT @retTableList(isLog,table_name,type) values(1,'tbl_suc_log',1)
  
 
INSERT @retTableList(isLog,table_name,type) values(0,'tbl_monitor',1)
 
 
INSERT @retTableList(isLog,table_name,type) values(1,'tbl_mail_log',1)
 
 
INSERT @retTableList(isLog,table_name,type) values(0,'tbl_process',2)      --没有时间
 
 
INSERT @retTableList(isLog,table_name,type) values(1,'tbl_daemon_log',1)
 
 
INSERT @retTableList(isLog,table_name,type) values(1,'tbl_download',1)
 
 
INSERT @retTableList(isLog,table_name,type) values(1,'tbl_sms_log',2)   --没有时间
 
 
    
    
RETURN
 
END

 

2、执行bcp和DOC命令

 

 CREATE  procedure dbo.backupData @vchServer    varchar(400),    --服务器
          @vchUser      varchar(16),     --用户名
          @vchPassword  varchar(32),     --密码
      @vchdirectory nvarchar(400),    --目录
          @vchStartTime varchar(30),     --起始时间
      @vchEndTime   varchar(30),      --截止时间
          @vchDataBase  varchar(200)     --数据库名称
 as
 
SET NOCOUNT ON
 
 
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
 
 
--E:zmworkspace sgprsdataBackupaa dd中文中 文?51101-20051101-20070411144610
 set @vchdirectory= REPLACE(@vchdirectory,' ','" "')--将空格转化
 
 
 
 
DECLARE @vchShell                 varchar(1024)
 
 
DECLARE @iIndex                   int           --下标
 DECLARE @iCount                   int           --最多表数
 DECLARE @vchTableName             varchar(64)
 
DECLARE @iType                    int           --1表示有时间,2表示没有时间
 DECLARE @iError                   int           --0(成功)或 1(失败)
 DECLARE @param                    int
 
SET     @param=0
 
SET     @iError=1
 
SET @iIndex=1
 
 
--建立目录
 DECLARE @vchMkDir nvarchar(400)
 
SET @vchMkDir='"mkdir  '+@vchdirectory+'"'
 
PRINT @vchMkDir
 
SET EXEC   @iError=master..xp_cmdshell   @vchMkDir
 
IF @iError<>0--建立目录失败
 BEGIN
     
RETURN 2
 
END
 
Set nocount on
 
BEGIN TRANSACTION
 
select @iCount=count(*from tableList()--查找最大数
 WHILE @iIndex<=@iCount
 
BEGIN
      
/*
     导出表结构定义,以用来导入数据
     EXEC master..xp_cmdshell 'bcp northwind..table1 format nul -f d: ormat1.fmt -c -T -S (local)eric -U sa -P 123321 '
     
*/

 
     
select @vchTableName=table_name,@iType=type from tableList() where id=@iIndex
     
SET @vchShell='bcp '+@vchDataBase+'..'+@vchTableName+'  format nul -f '
     
SET @vchShell=@vchShell+@vchdirectory+@vchTableName+'.fmt -c -T -S '+@vchServer+' -U  '+@vchUser+' -P '+@vchPassword
     
SET EXEC @iError=master..xp_cmdshell @vchShell
     
IF @iError<>0
     
BEGIN
         
print '导出结构出错'
         
print @vchShell
         
print @iError
         
ROLLBACK TRANSACTION
         
BREAK;
     
END
 
      
/*
     按查询导出表内容
     exec xp_cmdshell 'bcp "select * from northwind..table1 where column1>100 and column1<1000 " queryout d:Test.txt  -c -S (local)eric -U sa -P 123321 '
     EXEC master..xp_cmdshell 'bcp "select * from fsgprs2..tbl_ftp  where gen_datetime>=''2006-11-12 12:09:55''    " queryout d:Test.txt  -c -S 127.0.0.1  -U sa -P  123321 '
     字符要有两个''
     
*/

     
SET @vchShell='bcp "select * from '+@vchDataBase+'..'+@vchTableName+' '
     
IF @iType=1 --按时间查
     BEGIN
         
IF @vchStartTime is not null  --查询时间不为空
         BEGIN
             
SET @vchStartTime= Rtrim(Ltrim(@vchStartTime))
             
IF @vchStartTime<>''
             
BEGIN
                
SET @param=1  -- 有参数
                SET @vchShell=@vchShell+' where gen_datetime>='''+@vchStartTime+'''  '
             
END
         
END
 
         
IF @vchEndTime is not null  --查询时间不为空
         BEGIN
             
SET @vchEndTime= Rtrim(Ltrim(@vchEndTime))
             
IF @vchEndTime<>''
             
BEGIN
                
IF @param>0   --有参数
                BEGIN
                    
SET @vchShell=@vchShell+' and gen_datetime<='''+@vchStartTime+'''  '
                
END
                
ELSE--还没有参数
                BEGIN
                    
SET @vchShell=@vchShell+' where gen_datetime<='''+@vchStartTime+'''  '
                
END
 
             
END
         
END
 
         
--SET @vchShell=@vchShell+' where gen_datetime>='''+@vchStartTime+''' and gen_datetime<='''+@vchEndTime+'''  '
 
     
END
     
SET @vchShell=@vchShell+'" queryout '+@vchdirectory+@vchTableName+'.dat  -c -S '+@vchServer+'  -U '+@vchUser+' -P  '+@vchPassword
     
PRINT  @vchShell
     
SET EXEC @iError=master..xp_cmdshell @vchShell
     
IF @iError<>0
     
BEGIN
         
print '导出内容出错'
         
print @iError
         
ROLLBACK TRANSACTION
         
BREAK;
     
END
     
SET @iIndex=@iIndex+1
 
 
END
 
IF @iError=0
 
BEGIN
     
COMMIT TRANSACTION
 
END
 
 
IF @iError<>0
 
BEGIN
    
--删除目录
 
     
SET @vchMkDir='"del /Q  '+@vchdirectory+'"'
     
DECLARE @iDeleteDir int
     
SET @iDeleteDir=1
     
SET EXEC   @iDeleteDir=master..xp_cmdshell   @vchMkDir
 
     
IF @iDeleteDir<>0--删除目录失败
     BEGIN
        
RETURN 3
     
END
     
 
END
 
RETURN @iError
 
SET QUOTED_IDENTIFIER OFF
 
GO

 

3、动态SQL

 

CREATE       PROCEDURE restoreData3
         
         
--@vchServer    varchar(400),    --服务器
         --@vchUser      varchar(16),     --用户名
         --@vchPassword  varchar(32),     --密码
     --@vchdirectory nvarchar(400)--,    --目录
         --@vchStartTime varchar(30),     --起始时间
     --@vchEndTime   varchar(30)      --截止时间
         @vchDataBase    nvarchar(200)    --数据库名称 
 
 
AS
 
--恢复数据,删除临时表
 --E:zmworkspace sgprsdataBackupaa dd中文中 文?51101-20051101-20070411144610
 --set @vchdirectory= REPLACE(@vchdirectory,' ','" "')--将空格转化
 DECLARE @vchShell                 nvarchar(1024)
 
DECLARE @vchParam                 varchar(1024--参数
 
 
DECLARE @iIndex                   int           --下标
 DECLARE @iCount                   int           --最多表数
 DECLARE @vchTableName             varchar(64)
 
DECLARE @iType                    int           --1表示有时间,2表示没有时间
 DECLARE @iError                   int           --0(成功)或 不为0(失败)--sql帮助错误sp_executesql,失败时返回的不一定是1,有可能是其他值
 SET     @iError=1                 
 
SET @iIndex=1
 
 
 
select @iCount=count(*from tableList()--查找最大数
 
 
 
--执行单表恢复数据,从根节点到叶子节点
 
 
SET @iIndex=1
 
WHILE @iIndex<=@iCount
 
BEGIN
      
/****恢复数据********/
     
select @vchTableName=table_name,@iType=type from tableList() where id=@iIndex
     
SET @vchShell=@vchDataBase+'..restore_'+@vchTableName
     
print @vchShell
     
     
     
--执行恢复
     SET EXEC @iError=master..sp_executesql @vchShell
     
print @iError
     
     
--删除临时表
     SET @vchShell='use '+@vchDataBase+';if exists (select * from dbo.sysobjects where id = object_id(N'''+@vchDataBase+'.[dbo].[temp_'+@vchTableName+']'') and '
 
     
SET @vchShell=@vchShell+' OBJECTPROPERTY(id, N''IsUserTable'') = 1) drop table '+@vchDataBase+'.[dbo].[temp_'+@vchTableName+']'
     
print @vchShell
     
SET @vchShell='drop table '+@vchDataBase+'..temp_'+@vchTableName
     
SET EXEC @iError=master..sp_executesql @vchShell
 
     
SET @iIndex=@iIndex+1
 
END
 
RETURN 0
 
 
GO
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值