我有以下表值函数来分割字符串。这工作得很好,从网上的其他地方抄袭,我认为这不是问题的原因,但包括在相关的情况下:
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
所以问题是:为什么使用特定的字段名称作为函数的参数会导致语法错误,我怎样才能实现我想要的呢?
答案 0 :(得分:6)
我猜想数据库设置为兼容模式80或更低。
如果它发生在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