Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 sql来分离人名字符串并输出首字母_Sql Server 2005_User Defined Functions - Fatal编程技术网

Sql server 2005 sql来分离人名字符串并输出首字母

Sql server 2005 sql来分离人名字符串并输出首字母,sql-server-2005,user-defined-functions,Sql Server 2005,User Defined Functions,如何让SQL接受一个测试并返回传入的每个单词的第一个字母 我想使用这个UDF为数据库中的人名生成首字母 名称可以是2个(fname,lname)或3个(…mname)字 我正在使用sql2005创建函数dbo.GetFirstLetter(@Array VARCHAR(1000),@separator VARCHAR(10)) CREATE FUNCTION dbo.GetFirstLetter ( @Array VARCHAR(1000), @separator VARCHAR(10)) R

如何让SQL接受一个测试并返回传入的每个单词的第一个字母

我想使用这个UDF为数据库中的人名生成首字母

名称可以是2个(fname,lname)或3个(…mname)字

我正在使用sql2005创建函数dbo.GetFirstLetter(@Array VARCHAR(1000),@separator VARCHAR(10))
CREATE FUNCTION dbo.GetFirstLetter ( @Array VARCHAR(1000), @separator VARCHAR(10)) 
RETURNS @resultTable TABLE 
    (parseValue VARCHAR(100))
AS
BEGIN

    DECLARE @separator_position INT 
    DECLARE @array_value VARCHAR(1000) 

    SET @array = @array + @separator

    WHILE patindex('%' + @separator + '%' , @array) <> 0 
    BEGIN

      SELECT @separator_position =  patindex('%' + @separator + '%', @array)
      SELECT @array_value = left(@array, @separator_position - 1)

        INSERT @resultTable
        VALUES (SUBSTRING(Cast(@array_value AS varchar), 1, 1))

      SELECT @array = stuff(@array, 1, @separator_position, '')
    END

    RETURN
END
返回@resultable表 (parseValue VARCHAR(100)) 作为 开始 声明@separator\u位置INT 声明@array_value VARCHAR(1000) 设置@array=@array+@分隔符 而patindex('%'+@separator+'%',@array)0 开始 选择@separator_position=patindex('%'+@separator+'%',@array) 选择@array\u value=left(@array,@separator\u位置-1) 插入@resultable 值(子字符串(强制转换(@array_value AS varchar),1,1)) 选择@array=stuff(@array,1,@separator\u position,“”) 结束 返回 结束 这应该适用于“Firstname Lastname”和“Firstname Middlename Lastname”组合

DECLARE @name AS NVARCHAR(50) 
SET @name = 'Firstname Middle Lastname' 


SELECT SUBSTRING(@name, 1, 1) +     --First initial
    SUBSTRING(@name, CHARINDEX(' ', @name) + 1, 1) +    --Middle/Last initial
    CASE WHEN 0 <>  CHARINDEX(' ', @name, CHARINDEX(' ', @name) + 1) -- More than two words 
        THEN SUBSTRING(@name, CHARINDEX(' ', @name, CHARINDEX(' ', @name) + 1) + 1, 1)  --Last initial
    ELSE '' --Have to add empty string to avoid NULLing entire result
    END
将@name声明为NVARCHAR(50)
SET@name='Firstname中间Lastname'
选择子字符串(@name,1,1)+--首字母
子字符串(@name,CHARINDEX('',@name)+1,1)+--中间/最后一个首字母
0 CHARINDEX(“”,@name,CHARINDEX(“”,@name)+1)时的大小写--超过两个单词
然后子字符串(@name,CHARINDEX(“”,@name,CHARINDEX(“”,@name)+1,1)--最后一个首字母
ELSE“”--必须添加空字符串以避免整个结果为空
结束

当然,如果用户因为某种原因在他们的名字中有一个空格,那么解析出来就会有问题,但我怀疑如果不将你的名字存储在单独的字段中,情况就是这样

这是我的解决方案,它有以下特点:

  • 它可以处理字符串中的任意多个名称。(也就是说,两者都小于两个且大于三个。)
  • 名称之间的所有空格都将保留
我知道OP已经指定他的案例中只能有2到3个名字。我不介意。我只是分享一个有效的解决方案,如果它对特定的问题不是最好的,那也没关系

下面是函数:

CREATE FUNCTION dbo.fnGetInitials (@name varchar(max))
RETURNS varchar(max)
AS BEGIN
  DECLARE @cutpos int, @spacepos int, @result varchar(max);
  DECLARE @cutlist TABLE (CutPos int, SpacePos int);

  SET @result = LTRIM(RTRIM(@name));

  SET @cutpos = 2;
  SET @spacepos = CHARINDEX(' ', @result);
  WHILE @spacepos > 0 BEGIN
    INSERT INTO @cutlist VALUES (@cutpos, @spacepos);
    SET @spacepos = @spacepos + 1;
    SET @cutpos = @spacepos + 1;
    SET @spacepos = CHARINDEX(' ', @result, @spacepos);
  END;

  DELETE FROM @cutlist WHERE CutPos >= SpacePos;

  SELECT @result = STUFF(@result, CutPos, SpacePos - CutPos, '')
  FROM @cutlist
  ORDER BY CutPos DESC;

  RETURN @result;
END;
下面是一个测试调用:

SELECT dbo.fnGetInitials('  John Ronald   Reuel  Tolkien    ');
结果是:

----------------------------------------------------------------------------------------------------
J R   R  Tolkien

您也可以通过xquery实现它

Declare @Xml XML
Declare @String Varchar(Max)
Declare @firstletter Varchar(Max)
Declare @delimiter Varchar(5) 
SET @delimiter=' '
SET @String= 'THIS IS SQL'
SET @Xml = cast(('<a>'+replace(@String,@delimiter,'</a><a>')+'</a>') AS XML) 

;WITH CTE AS 
(SELECT A.value('.', 'varchar(max)') as [Column]FROM @Xml.nodes('a') AS FN(a) )
 SELECT Stuff((SELECT '' + LEFT([Column],1)from CTE 
 FOR XML PATH ('') ),1,0,'') 
Declare@Xml
声明@String Varchar(最大值)
声明@firstletter Varchar(最大值)
声明@delimiter Varchar(5)
设置@delimiter=''
SET@String='这是SQL'

SET@Xml=cast(“

图片比描述好100倍。下面是UDF声明的示例:

CREATE FUNCTION dbo.GetOnlyFirstLetters(@str NVARCHAR(4000),@sep NVARCHAR(10) )
RETURNS NVARCHAR(100)
AS
BEGIN
   DECLARE @textXML XML

   SELECT   @textXML = CAST('<d>' + replace(@str, @sep, '</d><d>') + '</d>' AS XML)

    DECLARE @result VARCHAR(8000)

    SET @result = ''

    SELECT  @result = @result + LEFT(T.split.value ('.', 'nvarchar(max)'), 1)
    FROM @textXML.nodes ('/d') T (split)

    RETURN  @result
END
GO
结果将是:

HKS

对于SQL Server 2017及更新版本:

CREATE FUNCTION dbo.fnGetFirstChars (@string NVARCHAR(max), @seperator NVARCHAR(MAX))
RETURNS NVARCHAR(max)

AS BEGIN

    DECLARE @result NVARCHAR(MAX)
    SELECT @result = STRING_AGG(SUBSTRING(value, 1, 1), '')
    FROM STRING_SPLIT(@string, @seperator)

RETURN @result
END;
CREATE FUNCTION dbo.fnGetFirstChars (@string NVARCHAR(max), @seperator NVARCHAR(MAX))
RETURNS NVARCHAR(max)

AS BEGIN

    DECLARE @result NVARCHAR(MAX)
    SELECT @result = STRING_AGG(SUBSTRING(value, 1, 1), '')
    FROM STRING_SPLIT(@string, @seperator)

RETURN @result
END;