SQL中的一些小技巧

C#和Sql中除法的小数点问题

在C#中整形的除法默认不保留小数,例如 var res = 3/10;  //res=0

如果需要得到更精确的数字,需要将整形转成decimal,float或者其他类型,例如 

var res = (3+0.0)/10;  //res=0.3

在SQL中也是类似,如 

print cast((3+0.0)/7 as numeric(3,2))  
//输出 0.43, 小数位过多可以通过转换成numeric,来舍去小数

 Sql中长度不足自动填充

主要就是利用right函数,从右边截取指定的长度

print right('000'+cast(1 as varchar),3)
--result: 001

 

 定义了varchar类型变量,但是忘记设长度,结果数据不正确尼玛调试了半天

如果没设长度,那应该默认的是1

declare @ola_no int
declare @ola_id varchar    --应该是varchar(11)!!!
select @ola_no=isnull(max(ola_no)+1,1) from KT_EXO_LabTimePeriod    --编号自增
select @ola_id=replace(convert(varchar(10),@sola_date,120),'-','')+right('000'+cast(@ola_no as varchar),3)

在if...else...中使用临时表会出现错误,比如

declare @para int
set @para=1
if @para=1
begin
    select bu_no,bu_name into #tmp from KT_B_Unit where bu_no=14
end
else
begin
    select bu_no,bu_name into #tmp  from KT_B_Unit where bu_no=15    
end
==============================================
消息 2714,级别 16,状态 1,第 10 行
数据库中已存在名为 '#tmp' 的对象。

在多个分支中,不能同时向一个临时表用select...into...from,比较笨的一种解决办法就是同时使用select...into...from 和insert into... select from ...。用select...into...from的时候创建临时表,而用insert into...select from...不会创建表,只会向已有的表中添加数据

declare @para int
set @para=1

select bu_no,bu_name into #tmp from KT_B_Unit where bu_no=15    

if @para=1
begin
    truncate table #tmp
    insert into #tmp select bu_no,bu_name from KT_B_Unit where bu_no=14
end

遇到错误"仅当使用了列的列表,并且 IDENTITY_INSERT 为 ON 时,才能在表 '@span' 中为标识列指定显式值。"

declare @span table(id int identity(0,1), bts_no int)
insert into @span select bts_no from KT_B_TimeSpan
--当表中有自增字段的时候,需要显示的指定要插入的列才行,并且这些列不能是自增字段
--将上面的插入sql语句改成
insert into @span (bts_no) select bts_no from KT_B_TimeSpan

 

 sql语句中in后面不能用变量的解决办法

如,select * from [table] where [column] in (@var)--@var是变量

sql语法是不允许这样的,有2种解决办法

1,用charindex搜索列是否存在变量中(返回值大于0)

declare @ids nvarchar(500)
set @ids='2,3,5,4' 
--select name from KT_U_Class where charindex(cast(id as varchar)+',',@ids+',') >0 
--这样会有个问题,例如当@ids='11', 然后正好有条数据id=1, 那么charindex(id+',', '11,')会错误地返回id=1的那条数据!解决办法就是在前面也加上个,号
select name from KT_U_Class where charindex(','+cast(id as varchar)+',',','+@ids+',') >0 

2,用exec()动态执行

declare @ids varchar(500)
set @ids='2,3,5,4'
exec('select name from KT_U_Class where id in ('+@ids+')')

如果要在语句中传递参数,那么可以用sp_executesql
declare @sql nvarchar(500)
declare @extia_no nvarchar(100)
declare @str nvarchar(500)
select @extia_no='98,99,100',@str=''
set @sql='select @nos=@nos+'',''+cast(extt_no as varchar) from KT_EX_TermItemArrange where extia_no in ('+@extia_no+')'
execute sp_executesql @stmt=@sql, @parms=N'@nos nvarchar(500) output', @nos=@str output
--select @str
select stuff(@str,1,1,'')

 Sql Server获取表信息,字段信息

View Code
--2005實現數據庫表字段屬性統計(2000里的系統表sysproperties描述表不存在,2005里用sys.extended_properties視圖替代)
select 
    [表名]=c.Name,
    [表说明]=isnull(f.[value],''),
    [列名]=a.Name,
    [列序號]=a.Column_id,
    [標識]=case when is_identity=1 then '' else '' end,
    [主鍵]=case when exists(select 1 from sys.objects x join sys.indexes y on x.Type=N'PK' and x.Name=y.Name 
                        join sysindexkeys z on z.ID=a.Object_id and z.indid=y.index_id and z.Colid=a.Column_id)
                    then '' else '' end,
    [類型]=b.Name,
    [字節數]=case when a.[max_length]=-1 and b.Name!='xml' then 'max/2G' 
            when b.Name='xml' then '2^31-1字節/2G'
            else rtrim(a.[max_length]) end,
    [長度]=case when ColumnProperty(a.object_id,a.Name,'Precision')=-1 then '2^31-1'
                else rtrim(ColumnProperty(a.object_id,a.Name,'Precision')) end,
    [小數]=isnull(ColumnProperty(a.object_id,a.Name,'Scale'),0),
    [是否為空]=case when a.is_nullable=1 then '' else '' end,
    [列说明]=isnull(e.[value],''),
    [默認值]=isnull(d.text,'')    
from 
    sys.columns a
left join
    sys.types b on a.user_type_id=b.user_type_id
inner join
    sys.objects c on a.object_id=c.object_id and c.Type='U'
left join
    syscomments d on a.default_object_id=d.ID
left join
    sys.extended_properties e on e.major_id=c.object_id and e.minor_id=a.Column_id and e.class=1 
left join
    sys.extended_properties f on f.major_id=c.object_id and f.minor_id=0 and f.class=1

SQL2000: -----------------------**********************************
ELECT 
    表名       = case when a.colorder=1 then d.name else '' end,
    表说明     = case when a.colorder=1 then isnull(f.value,'') else '' end,
    字段序号   = a.colorder,
    字段名     = a.name,
    标识       = case when COLUMNPROPERTY( a.id,a.name,'IsIdentity')=1 then ''else '' end,
    主键       = case when exists(SELECT 1 FROM sysobjects where xtype='PK' and parent_obj=a.id and name in (
                     SELECT name FROM sysindexes WHERE indid in(
                        SELECT indid FROM sysindexkeys WHERE id = a.id AND colid=a.colid))) then '' else '' end,
    类型       = b.name,
    占用字节数 = a.length,
    长度       = COLUMNPROPERTY(a.id,a.name,'PRECISION'),
    小数位数   = isnull(COLUMNPROPERTY(a.id,a.name,'Scale'),0),
    允许空     = case when a.isnullable=1 then ''else '' end,
    默认值     = isnull(e.text,''),
    字段说明   = isnull(g.[value],'')
FROM 
    syscolumns a
left join 
    systypes b 
on 
    a.xusertype=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  
left join 
    sysproperties f 
on 
    d.id=f.id and f.smallid=0
where 
    d.name='要查询的表'    --如果只查询指定表,加上此条件
order by 
    a.id,a.colorder

 

 

 

 

 

 

 

posted @ 2012-08-03 17:28  中本傻  阅读(431)  评论(0编辑  收藏  举报