我目前正在开发一个项目,用于将数据从一个表导入另一个表。我试图将包含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个不同的列?
答案 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)))
但最好的解决方案是反过来做。使用firstName
,lastName
和middleInitial
的实列标准化数据,并为fullName
执行计算列。
上面代码中的表达式可能需要更多的工作,因为我相信它们可以更有效地编写。我只是让他们努力表明这个想法。
创建计算列后,您可以这样做:
select firstName
,lastName
,middleInitital
from UserInfo