3

我有这个功能:

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值被移动了一列,并且继续到最后一列。

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

4

1 回答 1

10

这源于使用*.

如果定义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即使它已被删除,它仍然显示列。

于 2013-10-13T17:11:29.930 回答