Question

I have this function:

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 

Sometimes it works correctly, but sometimes column names doesn't match values like (I have written a sample results with fewer columns just to show the problem):

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

As you see color and Image values are shifted one column and this continues to the last column.

Can anyone tell me where the problem is?

Était-ce utile?

La solution

This arises from using *.

If the definition of ads changes (columns added or removed) this can mess up the metadata associated with the TVF.

You would need to run sp_refreshsqlmodule on it to refresh this metadata after such changes. It is best to avoid * in view definitions or inline TVFs for this reason.

An example of this

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()

Returns

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

Note that the D and E values are shown in the wrong columns. It still shows column C even though it has been dropped.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top