SQLServer中有两个扩展存储过程实现Scanf和Printf功能,恰当的使用它们可以在提取和拼接字符串时大幅度简化SQL代码。
1、xp_sscanf,用它可以分解格式相对固定的字符串,这对于厌倦使用一堆substring和charindex的朋友来说不错。比如前几天的一个帖子中提出的如何分解ip地址,相对简练且通用的代码应该是下面这样
if (
object_id (
'f_getip' )
is
not
null )
drop
function
f_getip
go
create
function
dbo
.
f_getip (
@
ip
varchar (
100 ))
returns
@
t
table (
a
int
, b
int
,
c
int
,
d
int )
as
begin
set
@
ip
=
replace (
@
ip
,
'.'
,
' ' )
declare
@
s1
varchar (
3 )
,
@
s2
varchar (
3
),
@
s3
varchar (
3 )
,
@
s4
varchar (
3 )
exec
xp_sscanf
@
ip
,
'%s %s %s %s'
,
@
s1
output
,
@
s2
output
,
@
s3
output
,
@
s4
output
insert
into
@
t
select
@
s1
,
@
s2
,
@
s3
,
@
s4
return
end
go
select
*
from
dbo
.
f_getip (
'192.168.0.1' )
go
/*
a b c d
----------- ----------- ----------- -----------
192 168 0 1
*/
2、xp_sprintf,用它可以拼接出一个字符串而不用担心过多的加号很引号难以控制,比如一个动态执行sql语句的存储过程
if (
object_id (
'p_select' )
is
not
null )
drop
proc
p_select
go
create
proc
p_select (
@
tb
varchar (
100
),
@
cols
varchar (
100
),
@
wherecol
varchar (
100
),
@
value
varchar (
100 ))
as
begin
declare
@ s
varchar (
8000 )
exec
xp_sprintf
@ s
output
,
'select %s from %s where %s=''%s'''
,
@
cols
,
@
tb
,
@
wherecol
,
@
value
exec (
@ s)
end
go
exec
p_select
'sysobjects'
,
'id,xtype,crdate'
,
'name'
,
'p_select'
/*
id xtype crdate
----------- ----- -----------------------
898102240 P 2009-08-18 03:01:51.153
*/