sqlsharpener icon indicating copy to clipboard operation
sqlsharpener copied to clipboard

Loading a view throws exception

Open pbolduc opened this issue 9 years ago • 3 comments
trafficstars

I am having troubles referencing any of my views. The error occurs in the Column class on line 103.

The following expression returns an empty list. The column it fails on is the first [Id] column of the view. It says it is a SqlComputedColumn. I do not know enough about the Microsoft.SqlServer.Dac.Model classes to try to resolve myself.

SqlObject.GetReferenced(dac.Column.DataType).ToList()
Error       Running transformation: System.InvalidOperationException: Sequence contains no elements
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at SqlSharpener.Model.Column..ctor(TSqlObject tSqlObject, TSqlObject tSqlTable, IEnumerable`1 primaryKeys, IDictionary`2 foreignKeys)
   at SqlSharpener.Model.View..ctor(TSqlObject tSqlObject, IEnumerable`1 primaryKeys, IDictionary`2 foreignKeys)
   at SqlSharpener.MetaBuilder.<>c__DisplayClass10.<LoadModel>b__9(TSqlObject sqlView)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at SqlSharpener.MetaBuilder.LoadModel(TSqlModel model)
   at SqlSharpener.MetaBuilder.LoadModel()
   at SqlSharpener.MetaBuilder.get_Tables()

SQL Scripts to repoduce

CREATE TABLE [dbo].[Port] (
    [Id]                 SMALLINT       IDENTITY (1, 1) NOT NULL,
    [Name]               VARCHAR (50)   NOT NULL,
    [Abbreviation]       VARCHAR (3)    NOT NULL,
    [Active]             BIT            NOT NULL,
    [Longitude]          DECIMAL (9, 6) NULL,
    [Latitude]           DECIMAL (9, 6) NULL,
    [PortTypeId]         SMALLINT       NOT NULL,
    [CreatedBy]          VARCHAR(255)   NOT NULL,
    [CreatedDateTime]    DATETIME2      NOT NULL,
    [UpdatedBy]          VARCHAR(255)       NULL,
    [UpdatedDateTime]    DATETIME2          NULL,
    [RowVersion]         ROWVERSION     NOT NULL,
    CONSTRAINT [PK_Port] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [CK_Port_Latitude_Latitude] CHECK ([Latitude] IS NULL AND [Longitude] IS NULL OR [Latitude] IS NOT NULL AND ([Latitude]>=(-90) AND [Latitude]<=(90)) AND [Longitude] IS NOT NULL AND ([Longitude]>=(-180) AND [Longitude]<=(180))),
    CONSTRAINT [FK_Port_PortTypeId] FOREIGN KEY ([PortTypeId]) REFERENCES [dbo].[PortType] ([Id]),
    CONSTRAINT [UQ_Port_Abbreviation] UNIQUE NONCLUSTERED ([Abbreviation] ASC),
    CONSTRAINT [UQ_Port_Name] UNIQUE NONCLUSTERED ([Name] ASC)
);
CREATE TABLE [dbo].[PortType]
(
    [Id]           SMALLINT      IDENTITY (1, 1) NOT NULL,
    [Name]         VARCHAR(20)   NOT NULL,
    [RowVersion]   ROWVERSION    NOT NULL,
    CONSTRAINT [PK_PortType] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [UX_PortType_Name] UNIQUE NONCLUSTERED ([Name] ASC)
)
CREATE VIEW [dbo].[RemotePort]
AS
SELECT [Port].*
  FROM [dbo].[Port]
 INNER JOIN [dbo].[PortType]
         ON [PortType].[Id] = [Port].[PortTypeId]
 WHERE [PortType].[Name] = 'Remote Port'

pbolduc avatar Mar 20 '16 03:03 pbolduc

I spent some time looking at this problem. When I used DacExplorer, I can see the column is defined as a ComputedColumn and type type references the origin table's column. My guess is the correct way to determine the view's column type is to look up the data type of the source table's column.

pbolduc avatar Mar 20 '16 21:03 pbolduc

Not sure if we can loop through the source columns used in the expression, but if we can we might be able to derive a type that will work. For example, if all columns are int then use int, else if all are numeric, but at least one is decimal or float then use float, else if any are a string then use string.

I think a work-around might be to wrap your expression in the view with CAST as in Cast((col1 + col2) as int) AS ColName.

aeslinger0 avatar Apr 08 '16 15:04 aeslinger0

I received a similar error in any table script where a column is a calculated column. I ended up having to modify my T4 to simple ignore any table that had a calculated column, as I tried multiple solutions to try to get it to work with the calculated column but had no luck.

chad206548 avatar Jul 14 '17 20:07 chad206548