前几天提问解答了自定义函数中不能使用临时表的问题(已加分结贴):
http://topic.csdn.net/u/20080416/15/1ce087cd-a02f-40ac-a863-f5fe2bb11e9c.html?272833094
可是在函数调用时有出现了问题,发现该函数不能以子查询出现在查询中:
函数调用
select min(DB) from dbo.Getdb('0200-35259250 ','3230-00601010 ')
结果
5100
函数作为子查询调用
select (select min(DB) from Getdb(A.MD001,A.MD003))
from BOMMD A where MD003='3230-00601010 ' and MD001='1300-00601105 '
结果
Msg 170, Level 15, State 1, Line 1
第 1 行: '.' 附近有语法错误。请高手解答,谢谢.
http://topic.csdn.net/u/20080416/15/1ce087cd-a02f-40ac-a863-f5fe2bb11e9c.html?272833094
可是在函数调用时有出现了问题,发现该函数不能以子查询出现在查询中:
函数调用
select min(DB) from dbo.Getdb('0200-35259250 ','3230-00601010 ')
结果
5100
函数作为子查询调用
select (select min(DB) from Getdb(A.MD001,A.MD003))
from BOMMD A where MD003='3230-00601010 ' and MD001='1300-00601105 '
结果
Msg 170, Level 15, State 1, Line 1
第 1 行: '.' 附近有语法错误。请高手解答,谢谢.
/*
标题:分解字符串并查询相关数据
作者:爱新觉罗.毓华
时间:2008-03-18
地点:广东深圳
说明:通过使用函数等方法分解字符串查询相关数据。问题:通过分解一个带某种符号分隔的字符串在数据库中查找相关数据。
例如 @str = '1,2,3',查询下表得到记录1,4,5,6
ID TypeID
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
6 6,7
*/
-----------------------------
create table tb (ID int , TypeID varchar(30))
insert into tb values(1 , '1,2,3,4,5,6,7,8,9,10,11,12')
insert into tb values(2 , '2,3')
insert into tb values(3 , '3,7,8,9')
insert into tb values(4 , '2,6')
insert into tb values(5 , '4,5')
insert into tb values(6 , '6,7')
go
-----------------------------
--如果仅仅是一个,如@str = '1'.
declare @str as varchar(30)
set @str = '1'
select * from tb where charindex(',' + @str + ',' , ',' + TypeID + ',') > 0
select * from tb where ',' + TypeID + ',' like '%,' + @str + ',%'
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
(所影响的行数为 1 行)
*/-----------------------------
--如果包含两个,如@str = '1,2'.
declare @str as varchar(30)
set @str = '1,2'
select * from tb where charindex(',' + left(@str , charindex(',' , @str) - 1) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',' , ',' + typeid + ',') > 0
select * from tb where ',' + typeid + ',' like '%,' + left(@str , charindex(',' , @str) - 1) + ',%' or
',' + typeid + ',' like '%,' + substring(@str , charindex(',' , @str) + 1 , len(@str)) + ',%'
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
4 2,6
(所影响的行数为 3 行)
*/-------------------------------------------
--如果包含三个或四个,用PARSENAME函数来处理.
declare @str as varchar(30)
set @str = '1,2,3,4'
select * from tb where
charindex(',' + parsename(replace(@str , ',' , '.') , 4) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + parsename(replace(@str , ',' , '.') , 3) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + parsename(replace(@str , ',' , '.') , 2) + ',' , ',' + typeid + ',') > 0 or
charindex(',' + parsename(replace(@str , ',' , '.') , 1) + ',' , ',' + typeid + ',') > 0
select * from tb where
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 4) + ',%' or
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 3) + ',%' or
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 2) + ',%' or
',' + typeid + ',' like '%,' + parsename(replace(@str , ',' , '.') , 1) + ',%'
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
(所影响的行数为 5 行)
*/---------------------------------------
--如果超过四个,则只能使用函数或动态SQL来分解并查询数据。
/*
名称:fn_split函数.
功能:实现字符串分隔功能的函数
*/
create function dbo.fn_split(@inputstr varchar(8000), @seprator varchar(10))
returns @temp table (a varchar(200))
as
begin
declare @i int
set @inputstr = rtrim(ltrim(@inputstr))
set @i = charindex(@seprator , @inputstr)
while @i >= 1
begin
insert @temp values(left(@inputstr , @i - 1))
set @inputstr = substring(@inputstr , @i + 1 , len(@inputstr) - @i)
set @i = charindex(@seprator , @inputstr)
end
if @inputstr <> '\'
insert @temp values(@inputstr)
return
end
go--调用
declare @str as varchar(30)
set @str = '1,2,3,4,5'select distinct m.* from tb m,
(select * from dbo.fn_split(@str,',')) n
where charindex(',' + n.a + ',' , ',' + m.typeid + ',') > 0drop table tb
drop function dbo.fn_split /*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
(所影响的行数为 5 行)
*/------------------------------------------
--使用动态SQL的语句。
declare @str varchar(200)
declare @sql as varchar(1000)
set @str = '1,2,3,4,5'
set @sql = 'select ''' + replace(@str , ',' , ''' as id union all select ''')
set @sql = @sql + ''''
set @sql = 'select distinct a.* from tb a , (' + @sql + ') b where charindex(' + ''','' + b.id + ' + ''',''' + ' , ' + ''','' + a.typeid + ' + ''',''' + ') > 0 '
exec (@sql)
/*
ID TypeID
----------- ------------------------------
1 1,2,3,4,5,6,7,8,9,10,11,12
2 2,3
3 3,7,8,9
4 2,6
5 4,5
(所影响的行数为 5 行)
*/看后半部分的:--调用
declare @str as varchar(30)
set @str = '1,2,3,4,5'select distinct m.* from tb m,
(select * from dbo.fn_split(@str,',')) n
where charindex(',' + n.a + ',' , ',' + m.typeid + ',') > 0
比如:
C001->B001.....->A001
函数得到B001的工单单别为5100
--少了个对象的所有者dbo
select (select min(DB) from dbo.Getdb(A.MD001,A.MD003))
from BOMMD A where MD003='3230-00601010' and MD001='1300-00601105'
1.函数单独调用
select min(DB) from dbo.Getdb('1300-00601105 ','3230-00601010 ')
结果:
5100
2.所使用的查询
select MD001,MD003
from BOMMD where MD001='1300-00601105 ' and MD003='3230-00601010 '
结果
MD001 MD003
1300-00601105 3230-00601010
3.函数作为上面查询的子查询
select A.*,(select min(DB) from dbo.Getdb(A.MD001,A.MD003)) AS t
from BOMMD A where MD001='1300-00601105 ' and MD003='3230-00601010 '
结果
Msg 170, Level 15, State 1, Line 1
第 1 行: '.' 附近有语法错误。这不是很奇怪吗?
RETURNS @t table(reno int,P1 CHAR(20),P2 CHAR(20),DB CHAR(4))
AS
BEGIN
declare @i int
set @i=1
insert into @t
select @i as reno,@part1 as P1,MD003 as P2,MC005 as DB
from BOMMD A
left join BOMMC B on A.MD001=B.MC001
where MD001=@part1while @@ROWCOUNT>0
begin
set @i=@i+1
insert into @t
select @i,@part1,MD003,MC005
from @t A
left join BOMMD B on A.P2=B.MD001
left join BOMMC C on B.MD001=C.MC001
where A.reno=@i-1 and not(B.MD001 is null)
end
delete @t where P2<>@part2
RETURN
end
我想: 你要的是min(db),
为什么 不函数直接返回出条件下(MD001,MD003)下的最小db这样调的方法就是select dbo.getdb(mdoo1,mdoo3)
from BOMMD
where MD001='1300-00601105' and MD003='3230-00601010'
RETURNS varchar(4)@t table(reno int,P1 CHAR(20),P2 CHAR(20),DB CHAR(4))
AS
BEGIN
declare @i int
declare @t table(reno int,P1 CHAR(20),P2 CHAR(20),DB CHAR(4))
set @i=1
insert into @t
select @i as reno,@part1 as P1,MD003 as P2,MC005 as DB
from BOMMD A
left join BOMMC B on A.MD001=B.MC001
where MD001=@part1 while @@ROWCOUNT>0
begin
set @i=@i+1
insert into @t
select @i,@part1,MD003,MC005
from @t A
left join BOMMD B on A.P2=B.MD001
left join BOMMC C on B.MD001=C.MC001
where A.reno=@i-1 and not(B.MD001 is null)
end
delete @t where P2 <>@part2
declare @mindb varchar(4)
select @mindb = min(db) from @tRETURN @mindb
end
调用:
select dbo.getdb(mdoo1,mdoo3)
from BOMMD
where MD001='1300-00601105' and MD003='3230-00601010'
RETURNS varchar(4)
AS
BEGIN
declare @i int
declare @t table(reno int,P1 CHAR(20),P2 CHAR(20),DB CHAR(4))
set @i=1
insert into @t
select @i as reno,@part1 as P1,MD003 as P2,MC005 as DB
from BOMMD A
left join BOMMC B on A.MD001=B.MC001
where MD001=@part1 while @@ROWCOUNT>0
begin
set @i=@i+1
insert into @t
select @i,@part1,MD003,MC005
from @t A
left join BOMMD B on A.P2=B.MD001
left join BOMMC C on B.MD001=C.MC001
where A.reno=@i-1 and not(B.MD001 is null)
end
delete @t where P2 <>@part2
declare @mindb varchar(4)
select @mindb = min(db) from @tRETURN @mindb
end
SQL codeselect dbo.getdb(mdoo1,mdoo3)
from BOMMD
where MD001='1300-00601105' and MD003='3230-00601010'
因为Getb返回的可能有多条记录,在函数中对多条记录删除留下一条?
我实际的需求是这样的:
需要从请购明细表上反映出每一个采购件都用在哪个工作中心.
分析如下:
请购单有记录订单号,由订单号可追溯成品编号
BOM表有记录主件工单别,工单别可反映工作中心所以就写了函数依据请购明细表每行的成品编码及采购件编码,到BOM表进行循环查找,获取该采购件在该成品中的位置并返回工单别.