在表值函数中使用SELECT外的CASE

时间:2018-05-14 13:04:44

标签: tsql

我试图从不同的表/视图中选择相同的列,具体取决于参数的值(@ruleset)。由于无法将表的名称作为参数传递,也无法在函数内部构造名称,因此在select语句之外使用了CASE结构。但是,我收到一个错误: "当子查询未与EXISTS一起引入时,只能在选择列表中指定一个表达式。" [希望我说得对,这是我的第一个问题。]

CREATE FUNCTION app.fgProduct 
(   
    @ruleset nvarchar(50),
    @matno nvarchar(50), 
    @datarevision int
)
RETURNS TABLE 
AS
RETURN 
(
SELECT
CASE WHEN @ruleset = 'G1' THEN 
(
  SELECT 
    @matno AS ProductId
    ,@datarevision AS DataRevision
    ,[ProductName]
  FROM [ruleset].[g1gxProduct]
  WHERE ProductId = @matno
)
WHEN @ruleset = 'G2' THEN 
(
  SELECT 
    @matno AS ProductId
    ,@datarevision AS DataRevision
    ,[ProductName]
  FROM [ruleset].[g2gxProduct]
  WHERE ProductId = @matno
)
END
)

还有很多其他观点,所以整个问题不能在一个程序中解决。以上是一个函数示例,用于根据各种规则集(=视图集)生成新记录。

3 个答案:

答案 0 :(得分:0)

CASE是一个表达式,不适用于条件流。请改用IF / ELSE

答案 1 :(得分:0)

该错误与在子查询中返回多个列的select语句有关。您只能在语句中返回一列:

SELECT 
    @matno AS ProductId
    ,@datarevision AS DataRevision
    ,[ProductName]

答案 2 :(得分:0)

解决方案是声明一个结果表并插入其中,就像评论中建议的@EzLo一样。

CREATE FUNCTION app.fgProduct 
(   
  @ruleset nvarchar(50),
  @matno nvarchar(50), 
  @datarevision int
)
RETURNS @ret TABLE (
  [ProductID] [nvarchar](50) NOT NULL,
  [DataRevision] [int] NOT NULL,
  [ProductName] [nvarchar](50) NULL
)
AS
BEGIN
IF @ruleset = 'G1'
  INSERT INTO @ret 
  SELECT 
    @matno AS ProductId
    ,@datarevision AS DataRevision
    ,[ProductName]
  FROM [ruleset].[g1gxProduct]
  WHERE ProductId = @matno
ELSE
IF @ruleset = 'G2'
  INSERT INTO @ret 
  SELECT 
    @matno AS ProductId
    ,@datarevision AS DataRevision
    ,[ProductName]
  FROM [ruleset].[g2gxProduct]
  WHERE ProductId = @matno
RETURN
END