【问题标题】:Return first five numbers form string within UDF从 UDF 中的字符串返回前五个数字
【发布时间】:2017-03-30 00:12:37
【问题描述】:

我正在研究SQL Server(2005、2008 和 2012)

我想通过使用 UDF 从 varchar 列中提取前五个数字

输入:

rrr123ddd4567ddd19828www2
123hhhsss124ss18762s
qq12349wsss12376ss

输出:

19828
18762
12349

我的足迹如下:

DECLARE 
    @myString VARCHAR(1000),
    @temp VARCHAR(100),
    @position INT,
    @ExecuteInsert nvarchar (500),
    @FirstChar bit

SET @myString = 'rrr123ddd4567ddd19828www2'
SET @position = 1 
SET @FirstChar = 1
WHILE @position <= LEN(@myString)
BEGIN
 IF (ISNUMERIC(SUBSTRING(@myString,@position,1))) = 1
     BEGIN
        SET @temp =  isnull(@temp,'') + SUBSTRING(@myString,@position,1)
        SET @FirstChar = 1
     END
 ELSE /* The char is alphabetical */
     BEGIN
     if (@FirstChar= 1)
        BEGIN
            SET @temp =  isnull(@temp,'') + ','
            SET @FirstChar = 0
        END
     END

SET @position = @position + 1
END 

IF (RIGHT(@temp,1) <> ',')
BEGIN
    SET @temp = @temp + ','
END


SELECT @temp = REPLACE(','+ @temp + ',',',,','')

SELECT @temp = Replace (@temp,',','''),(''') 

Select @temp = '(''' + @temp + ''')'
Create table #temp
(
    col1 varchar(100)
)
SET @ExecuteInsert = 'insert into #temp values ' + @temp

Execute sp_executesql @ExecuteInsert

select top 1 col1 from #temp
where LEN(col1) = 5
drop table #temp

-- Output >> 19828

前面的查询与字符串输入配合得很好,但我想在UDF 中使用此代码以将其与列一起使用。

如果我在 UDF 中使用上一个查询,则会引发以下错误:

无法从函数内访问临时表。

编辑

如果我使用 Table variable ,我会得到下一个错误:

只能执行函数和一些扩展存储过程 从函数内部。

任何帮助将不胜感激。

【问题讨论】:

  • 更改代码以使用表变量而不是临时表。
  • @R.Richards 将其更改为表变量后出现此错误找不到列“dbo”或用户定义的函数或聚合“dbo.GetFirstFiveNumbers”,或者名称不明确。

标签: sql-server replace substring user-defined-functions


【解决方案1】:
CREATE FUNCTION udfTest
(
-- Add the parameters for the function here

)
RETURNS int
AS
BEGIN
-- Declare the return variable here
DECLARE
@Result int, 
@myString VARCHAR(1000),
@temp VARCHAR(100),
@position INT,
@ExecuteInsert nvarchar (500),
@FirstChar bit

SET @myString = 'rrr123ddd4567ddd19828www2'
SET @position = 1 
SET @FirstChar = 1
WHILE @position <= LEN(@myString)
BEGIN
 IF (ISNUMERIC(SUBSTRING(@myString,@position,1))) = 1
 BEGIN
SET @temp =  isnull(@temp,'') + SUBSTRING(@myString,@position,1)
SET @FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (@FirstChar= 1)
BEGIN
    SET @temp =  isnull(@temp,'') + ','
    SET @FirstChar = 0
END
END

SET @position = @position + 1
END 

IF (RIGHT(@temp,1) <> ',')
BEGIN
SET @temp = @temp + ','
END

SELECT @temp = REPLACE(','+ @temp + ',',',,','')

SELECT @temp = Replace (@temp,',','''),(''') 

 Select @temp = '(''' + @temp + ''')'
 Declare @tempTable TABLE
 (
 col1 varchar(100)
 )

 insert into @tempTable SELECT @temp

 select top 1 @Result=col1 from @tempTable
 where LEN(col1) = 5
 return @Result
 END
 GO

【讨论】:

  • 如何在内联函数中使用表变量?? ..返回表后出现下一个错误>>>找不到列“dbo”或用户定义的函数或聚合“dbo.GetFirstFiveNumbers”,或者名称不明确。
  • 请参阅此链接sqlhints.com/tag/table-variables-in-user-defined-function,了解如何在用户定义的函数中使用表变量
  • 它不起作用,我想从@tempTable返回值的主要问题,内联函数怎么来??
  • 我得到下一个错误:只有函数和一些扩展存储过程可以在函数内执行。
  • select top 1 @Result=col1 from @tempTable where LEN(col1) = 5 it is not working
【解决方案2】:

这是我对我问题的回答,希望对其他人有所帮助。

目标是创建UDF 函数以将其与列一起使用,而不仅仅是固定值。

方法是使用SplitString 而不是sp_executesql

用于拆分逗号分隔的字符串并将其值循环到表中。

演示:-

Create table DummyTable
( col1 varchar (100))
go

Insert into DummyTable values ('rrr123ddd4567ddd19828www2')
Insert into DummyTable values ('123hhhsss124ss18762s')
Insert into DummyTable values ('qq12349wsss12376ss')

go

/*
    SplitString via Mudassar Khan
    http://www.aspsnippets.com/Articles/Split-and-convert-Comma-Separated-Delimited-String-to-Table-in-SQL-Server.aspx
*/
Create FUNCTION SplitString
(    
      @Input NVARCHAR(MAX),
      @Character CHAR(1)
)
RETURNS @Output TABLE (
      Item NVARCHAR(1000)
)
AS
BEGIN
      DECLARE @StartIndex INT, @EndIndex INT

      SET @StartIndex = 1
      IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
      BEGIN
            SET @Input = @Input + @Character
      END

      WHILE CHARINDEX(@Character, @Input) > 0
      BEGIN
            SET @EndIndex = CHARINDEX(@Character, @Input)

            INSERT INTO @Output(Item)
            SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

            SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
      END

      RETURN
END
GO

-------------------------------------
-------------------------------------
-------------------------------------

/*
    My Own Function
*/

Create FUNCTION udfGetFirstFiveNumbers
(
@myString VARCHAR(1000)
)
RETURNS varchar(100)
AS
BEGIN
DECLARE
@temp VARCHAR(100),
@result Varchar (100),
@position INT,
@ExecuteInsert nvarchar (500),
@FirstChar bit

SET @position = 1 
SET @FirstChar = 1
WHILE @position <= LEN(@myString)
BEGIN
 IF (ISNUMERIC(SUBSTRING(@myString,@position,1))) = 1
 BEGIN
SET @temp =  isnull(@temp,'') + SUBSTRING(@myString,@position,1)
SET @FirstChar = 1
END
ELSE /* The char is alphabetical */
BEGIN
if (@FirstChar= 1)
BEGIN
    SET @temp =  isnull(@temp,'') + ','
    SET @FirstChar = 0
END
END

SET @position = @position + 1
END 

IF (RIGHT(@temp,1) <> ',')
BEGIN
SET @temp = @temp + ','
END

SELECT @temp = REPLACE(','+ @temp + ',',',,','')

SELECT @result = Item
FROM dbo.SplitString(@temp, ',')
where len(Item) = 5

return @result
 END
 GO

--  Test

select col1, dbo.udfGetFirstFiveNumbers(col1) as result
from DummyTable

结果:-

【讨论】:

    猜你喜欢
    • 2011-01-10
    • 2013-04-03
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 2018-05-20
    • 2012-10-15
    • 2020-11-02
    • 1970-01-01
    相关资源
    最近更新 更多