T语句在select语句中解析文本

时间:2012-09-28 09:58:26

标签: tsql sql-server-2005 select stored-procedures

我目前正在开发一个项目,用于将数据从一个表导入另一个表。我试图将包含FULLNAME的字段解析为LAST,FIRST,MI。这些名称都是“LAST,FIRST MI”的格式我编写了一个存储过程,可以正确地解析并返回结果,但我不确定如何将存储过程压缩到单个select语句中。例如,我目前有:

SELECT FULLNAME From UserInfo

我想拥有的是这样的:

SELECT Last, First, MI from UserInfo

目前我的存储过程采用ParseName的形式(FULLNAME,Last as OUTPUT,First as OUTPUT,MI as OUTPUT)。如何调用此过程并将输出变量拆分为3个不同的列?

3 个答案:

答案 0 :(得分:1)

您可以将存储过程的结果放在(临时)表中,如下所示(我添加了FULLNAME列以提供连接条件,您必须调整存储过程才能执行此操作):

CREATE TABLE #temp (
  FULLNAME NVARCHAR(..)
  ,Last NVARCHAR(..)
  ,First NVARCHAR(..)
  ,MI NVARCHAR(..)
);

INSERT INTO #temp (Last, First, MI)
EXECUTE MySproc;

如果您希望能够在结构上执行SELECT Last, First, MI from UserInfo,则必须先向UserInfo添加三列以获取您的名称信息,然后插入从存储过程中获取的已解析数据。

修改

您提到使用SELECT ... INTO ...将数据放入新表中。我猜测新表没有FULLNAME列,然后你最好使用表值函数(如this answer建议的那样)。但是,如果保留FULLNAME列,则可以使用该列将临时表与新表连接以更新新表,如下所示:

UPDATE NUI
  SET NUI.Last = T.Last, NUI.First = T.First, NUI.MI = T.MI
  FROM NewUserInfo AS NUI
  INNER JOIN #temp AS T ON NUI.FULLNAME = T.FULLNAME;

如果您的新表中没有UPDATE列,则可以将此FULLNAME方法与其他连接条件一起使用,但请确保事先运行良好的测试以检查连接是否成立

希望这有帮助,祝你好运!

答案 1 :(得分:1)

将您的存储过程替换为table valued function。然后,您可以将此函数应用于所有行。

下面是一个示例 - 只需将您的逻辑用于解析名称

create FUNCTION dbo.f_parseName(@inFullName varchar(255))
RETURNS 
    @tbl TABLE (lastName varchar(255), firstName varchar(255), middleName varchar(255))
as
BEGIN
-- put your logic here
insert into @tbl(lastName,firstName,middleName)
select substring(@inFullName,0,10),substring(@inFullName,11,10), substring(@inFullName,21,10)

return

end

应用功能

-- sample data
declare @fullNames table (fullName varchar(255))
insert into @fullNames (fullName) values
('111111111122222222223333333333')
,('AAAAAAAAAABBBBBBBBBBCCCCCCCCCC')


select 
    fn.fullName
    ,pn.lastName
    ,pn.firstName
    ,pn.middleName
from 
    @fullNames fn
    cross apply dbo.f_parseName(fn.fullName) pn

答案 2 :(得分:0)

您可以将计算列添加到表中,如下所示:

alter table UserInfo
    add firstName as SUBSTRING(fullName, CHARINDEX(',',fullName,0)+2, LEN(fullName)-CHARINDEX(',',fullName,0)-CHARINDEX(' ', REVERSE(fullName),0)-1)
        ,lastName as SUBSTRING(fullName, 0, CHARINDEX(',',fullName,0))
        ,middleInitital as REVERSE(SUBSTRING(REVERSE(fullName),0,CHARINDEX(' ', REVERSE(fullName),0)))

但最好的解决方案是反过来做。使用firstNamelastNamemiddleInitial的实列标准化数据,并为fullName执行计算列。

上面代码中的表达式可能需要更多的工作,因为我相信它们可以更有效地编写。我只是让他们努力表明这个想法。

创建计算列后,您可以这样做:

select  firstName
        ,lastName
        ,middleInitital
from UserInfo