【问题标题】:Error calling t-sql function调用 t-sql 函数时出错
【发布时间】:2015-02-16 19:35:27
【问题描述】:

这里显示了一个表值函数:

ALTER FUNCTION [dbo].[SplitStr]
   (@sep char(1), @s nvarchar(512))
RETURNS table
AS
    RETURN (
    WITH Pieces(pn, start, stop) AS (
        SELECT 1, 1, CHARINDEX( @sep, @s )
        UNION ALL
        SELECT pn + 1, stop + 1, CHARINDEX( @sep, @s, stop + 1 )
        FROM Pieces
        WHERE stop > 0
    )
    SELECT
        pn,
        SUBSTRING( @s, start, CASE WHEN stop > 0 THEN stop-start ELSE 512 END ) AS s
    FROM
        Pieces
)

我现在尝试从另一个脚本中调用它,如下所示:

declare @referencestring varchar(512)
declare @s varchar(512)

set @s = 'cow is running|-reference_temp|horse is jumping';

set @referencestring = (select ss.val 
                        from (select dbo.SplitStr(@s, '|') as val) ss 
                        where ss.val like '%-reference%');

但是这样做会给我错误:

找不到列“dbo”或用户定义的函数或聚合“dbo.SplitStr”,或者名称不明确。

我想要做的是从 split 函数返回的表有三行,我只想要包含字符串 -reference 的行作为字符串。它应该存储在referencestring 变量中。

【问题讨论】:

  • 尝试单独执行 select dbo.SplitStr(@s, '|')。那不应该是 select * from dbo.SplitStr(@s, '|') 吗?
  • 你的函数返回一个表。你需要说SELECT <cols> FROM dbo.function(...);,而不是SELECT dbo.function(...);。无论如何,这不是拆分字符串的最有效方法 - 请参阅sqlperformance.com/2012/07/t-sql-queries/split-strings,更重要的是,sqlperformance.com/2012/08/t-sql-queries/…
  • @Aaron - 谢谢,但我应该写什么来代替
  • @shawnt00 - 数据库不正确且函数确实存在。
  • @schudel - 是的 select * from dbo.SplitStr('some string', '|') 给出输出,但输出错误。它只包含一行两列 --> 1, |

标签: sql sql-server-2008 string-split


【解决方案1】:

基于 Aarons 链接,这是可行的:

CREATE FUNCTION dbo.SplitStrings_Moden
(
   @List NVARCHAR(MAX),
   @Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING AS
RETURN
  WITH E1(N)        AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
                         UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 
                         UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1),
       E2(N)        AS (SELECT 1 FROM E1 a, E1 b),
       E4(N)        AS (SELECT 1 FROM E2 a, E2 b),
       E42(N)       AS (SELECT 1 FROM E4 a, E2 b),
       cteTally(N)  AS (SELECT 0 UNION ALL SELECT TOP (DATALENGTH(ISNULL(@List,1))) 
                         ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E42),
       cteStart(N1) AS (SELECT t.N+1 FROM cteTally t
                         WHERE (SUBSTRING(@List,t.N,1) = @Delimiter OR t.N = 0))
  SELECT Item = SUBSTRING(@List, s.N1, ISNULL(NULLIF(CHARINDEX(@Delimiter,@List,s.N1),0)-s.N1,8000))
    FROM cteStart s;

go


declare @referencestring varchar(512)
declare @s varchar(512)

set @s = 'cow is running|-reference_temp|horse is jumping';

set @referencestring = (select item from dbo.SplitStrings_Moden(@s, '|') 
                        where item like '%-reference%');

print @referencestring

【讨论】:

  • 感谢您的时间好友。是的,这给出了正确的答案。
  • 在该页面上的所有变体中,至少从性能指标来看,选择一个多么奇怪。
  • 很公平。我基本上随机选择了一个,只是为了说明调用表值函数的正确方法。
  • @AaronBertrand - 谢谢,但你更喜欢哪一个? XML 之一?
  • @VVV 老实说,我更喜欢not split strings in the first place。数据库看到 a|delimited|string 而不是三个不同的值是否有原因?
猜你喜欢
  • 1970-01-01
  • 2010-09-26
  • 1970-01-01
  • 2012-07-22
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多