【问题标题】:SQL Server: results of the table valued function doesn't match column namesSQL Server:表值函数的结果与列名不匹配
【发布时间】:2013-10-13 17:04:44
【问题描述】:

我有这个功能:

CREATE FUNCTION [dbo].[full_ads](@date SMALLDATETIME)
returns TABLE
AS
    RETURN
      SELECT *,
             COALESCE((SELECT TOP 1 ptype
                       FROM   special_ads
                       WHERE  [adid] = a.id
                              AND @date BETWEEN starts AND ends), 1) AS ptype,
             (SELECT TOP 1 name
              FROM   cities
              WHERE  id = a.cid)                                     AS city,
             (SELECT TOP 1 name
              FROM   provinces
              WHERE  id = (SELECT pid
                           FROM   cities
                           WHERE  id = a.cid))                       AS province,
             (SELECT TOP 1 name
              FROM   models
              WHERE  id = a.mid)                                     AS model,
             (SELECT TOP 1 name
              FROM   car_names
              WHERE  id = (SELECT car_id
                           FROM   models
                           WHERE  id = a.mid))                       AS brand,
             (SELECT TOP 1 pid
              FROM   cities
              WHERE  id = a.cid)                                     pid,
             (SELECT TOP 1 car_id
              FROM   models
              WHERE  id = a.mid)                                     bid,
             (SELECT TOP 1 name
              FROM   colors
              WHERE  id = a.color_id)                                AS color,
             COALESCE((SELECT TOP 1 fileid
                       FROM   carimgs
                       WHERE  adid = a.id), 'nocarimage.png')        AS [image]
      FROM   ads a
      WHERE  isdeleted <> 1 

有时它可以正常工作,但有时列名与值不匹配(我编写了一个包含较少列的示例结果只是为了显示问题):

ID      Name      City      Color       Image
----------------------------------------------
1      John     New York    Null         Red 
2      Ted      Chicago     Null         Blue

如您所见,colorImage 值移动了一列,并继续到最后一列。

谁能告诉我问题出在哪里?

【问题讨论】:

  • 您可能需要发布完整的输出,会不会是您的一个 WHERE 案例没有找到匹配项而导致后续列丢失?
  • 我没有给出真实结果的原因是,它不是英文的,您可能无法识别这些值。但在所有可能找不到匹配项的情况下,我使用了 coalesce(假设返回值为 null)

标签: sql-server stored-functions


【解决方案1】:

这源于使用*

如果ads 的定义发生更改(添加或删除列),这可能会弄乱与 TVF 关联的元数据。

您需要在其上运行 sp_refreshsqlmodule 以在此类更改后刷新此元数据。出于这个原因,最好避免在视图定义或内联 TVF 中使用 *

一个例子

CREATE TABLE T
(
A CHAR(1) CONSTRAINT DF_A DEFAULT 'A',
B CHAR(1) CONSTRAINT DF_B DEFAULT 'B',
C CHAR(1) CONSTRAINT DF_C DEFAULT 'C',
D CHAR(1) CONSTRAINT DF_D DEFAULT 'D'
)

GO

INSERT INTO T DEFAULT VALUES

GO

CREATE FUNCTION F()
RETURNS TABLE
AS
    RETURN
    SELECT * FROM T

GO

SELECT * FROM F()

GO

ALTER TABLE T DROP CONSTRAINT DF_C, COLUMN  C

ALTER TABLE T ADD E CHAR(1) DEFAULT 'E' WITH VALUES

GO

SELECT * FROM F()

返回

+---+---+---+---+
| A | B | C | D |
+---+---+---+---+
| A | B | D | E |
+---+---+---+---+

请注意,DE 值显示在错误的列中。即使它已被删除,它仍会显示列 C

【讨论】:

  • 伟大的。是的,令人兴奋的是,这个程序解决了它。但正如你所说,我必须删除 *.非常感谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-23
  • 2020-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多