Domanda

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?

È stato utile?

Soluzione

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top