“语法错误”在T-SQL查询的SELECT子句中使用表值函数

时间:2011-02-24 10:53:20

标签: sql-server tsql

我有以下表值函数来分割字符串。这工作得很好,从网上的其他地方抄袭,我认为这不是问题的原因,但包括在相关的情况下:

CREATE FUNCTION dbo.StringSplit (@sep char(1), @s varchar(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
)
GO

这将启用以下行:

SELECT * FROM dbo.StringSplit('.', 'this.is.a.string.to.split')

生产

 pn | s
----+--------
 1  | this
 2  | is
 3  | a
 4  | string
 5  | to
 6  | split

我的目标是从包含大量文件名的表中获取文件扩展名列表。为此,我使用上面的表值函数来分割每个文件名:

SELECT
  doc_id,
  doc_file_name,
  (SELECT TOP 1 s FROM dbo.StringSplit('.', doc_file_name) ORDER BY pn DESC) AS extension
FROM
  ai_docs_core

让SQL Server企业管理器检查语法,这会在包含该函数的行上出现语法错误:

Msg 102, Level 15, State 1, Line 34
Incorrect syntax near 'doc_file_name'.

以下不能满足我的需要(显然,因为它使用的是set变量),但它不会导致语法错误:

DECLARE @foo VARCHAR(512) = 'my_filename.doc'
SELECT
  doc_id,
  doc_file_name,
  (SELECT TOP 1 s FROM dbo.StringSplit('.', @foo) ORDER BY pn DESC) AS extension
FROM
  ai_docs_core

所以问题是:为什么使用特定的字段名称作为函数的参数会导致语法错误,我怎样才能实现我想要的呢?

1 个答案:

答案 0 :(得分:6)

我猜想数据库设置为兼容模式80或更低。

请参阅sp_dbcmptlevel

如果它发生在FROM子句

中,这通常是原因

您也可以像这样写

SELECT
  a.doc_id,
  a.doc_file_name,
  foo.extension 
FROM
  ai_docs_core a
  OUTER APPLY
  (SELECT TOP 1 s AS extension
   FROM dbo.StringSplit('.', a.doc_file_name)
   ORDER BY pn DESC
  ) foo