Transact SQL 调用函数的子查询语法不正确
Transact SQL Subquery calling a function incorrect syntax
我在“.”附近得到一个不正确的语法并且似乎无法在以下代码中确定原因:
select
o.object_id,
(select top 1 Zone from dbo.getzone(o.object_id)) as Zone from object as o
getzone 是一个 table 值函数,当我直接引用它时,或者如果我将特定的 object_id 放入其中,它可以完美地工作,但每次我尝试使其动态化时,我都会得到语法错误。
我错过了什么?
修复您的别名
select o.object_id,
(select top 1 Zone from dbo.getzone(o.object_id)) as Zone
from object AS o
你不能那样做。您需要一个 returns 只有一个结果的标量版本。如果需要,它可以只是一个包装脚本。像这样:
CREATE FUNCTION [dbo].[getSingleZone](@object_id varchar(20))
RETURNS varchar(20)
AS
BEGIN
DECLARE @Zone varchar(20)
select @Zone = max(Zone) from dbo.getzone(@object_id)
return @Zone
END
select
o.object_id,
dbo.getSingleZone(o.object_id) as Zone from object o
我不知道你的数据类型,所以我猜了。
也许我遗漏了问题所在,但这似乎有效。使用内置函数的名称 (OBJECT_ID
) 作为列名可能没有帮助。
SQL fiddle 下面的示例或代码。
-- TVF without parameter.
create function dbo.GetZone()
returns table as
return
select Id, Letter
from
( values ( 1, 'Aleph' ), ( 2, 'Beth' ), ( 3, 'Gimmel' ) ) as Letters( Id, Letter );
go
-- TVF with parameter;
create function dbo.GetZone2( @Id as Int )
returns table as
return
select Id, Letter
from dbo.GetZone() where Id = @Id;
go
select * from dbo.GetZone();
select * from dbo.GetZone2( 2 );
-- Sample table and data.
declare @Objects as table ( Id Int Identity, Letter VarChar(16) );
insert into @Objects values ( 'Alpha' ), ( 'Beta' ), ( 'Gamma' );
select * from @Objects;
-- Correlated subquery.
select O.Id, O.Letter as [Greek],
( select top 1 Letter from dbo.GetZone( ) where Id = O.Id ) as [Hebrew]
from @Objects as O;
select O.Id, O.Letter as [Greek],
( select top 1 Letter from dbo.GetZone2( O.Id ) ) as [Hebrew]
from @Objects as O;
-- Houseclean.
drop function dbo.GetZone;
drop function dbo.GetZone2;
我在“.”附近得到一个不正确的语法并且似乎无法在以下代码中确定原因:
select
o.object_id,
(select top 1 Zone from dbo.getzone(o.object_id)) as Zone from object as o
getzone 是一个 table 值函数,当我直接引用它时,或者如果我将特定的 object_id 放入其中,它可以完美地工作,但每次我尝试使其动态化时,我都会得到语法错误。
我错过了什么?
修复您的别名
select o.object_id,
(select top 1 Zone from dbo.getzone(o.object_id)) as Zone
from object AS o
你不能那样做。您需要一个 returns 只有一个结果的标量版本。如果需要,它可以只是一个包装脚本。像这样:
CREATE FUNCTION [dbo].[getSingleZone](@object_id varchar(20))
RETURNS varchar(20)
AS
BEGIN
DECLARE @Zone varchar(20)
select @Zone = max(Zone) from dbo.getzone(@object_id)
return @Zone
END
select
o.object_id,
dbo.getSingleZone(o.object_id) as Zone from object o
我不知道你的数据类型,所以我猜了。
也许我遗漏了问题所在,但这似乎有效。使用内置函数的名称 (OBJECT_ID
) 作为列名可能没有帮助。
SQL fiddle 下面的示例或代码。
-- TVF without parameter.
create function dbo.GetZone()
returns table as
return
select Id, Letter
from
( values ( 1, 'Aleph' ), ( 2, 'Beth' ), ( 3, 'Gimmel' ) ) as Letters( Id, Letter );
go
-- TVF with parameter;
create function dbo.GetZone2( @Id as Int )
returns table as
return
select Id, Letter
from dbo.GetZone() where Id = @Id;
go
select * from dbo.GetZone();
select * from dbo.GetZone2( 2 );
-- Sample table and data.
declare @Objects as table ( Id Int Identity, Letter VarChar(16) );
insert into @Objects values ( 'Alpha' ), ( 'Beta' ), ( 'Gamma' );
select * from @Objects;
-- Correlated subquery.
select O.Id, O.Letter as [Greek],
( select top 1 Letter from dbo.GetZone( ) where Id = O.Id ) as [Hebrew]
from @Objects as O;
select O.Id, O.Letter as [Greek],
( select top 1 Letter from dbo.GetZone2( O.Id ) ) as [Hebrew]
from @Objects as O;
-- Houseclean.
drop function dbo.GetZone;
drop function dbo.GetZone2;