用主键创建视图?

Posted

技术标签:

【中文标题】用主键创建视图?【英文标题】:Create view with primary key? 【发布时间】:2012-07-11 09:43:55 【问题描述】:

我用以下代码创建了一个视图

SELECT
    CONVERT(NVARCHAR, YEAR(okuma_tarihi)) + 'T1' AS sno,
    YEAR(okuma_tarihi) AS Yillar,
    SUM(toplam_kullanim_T1) AS TotalUsageValue, 'T1' AS UsageType
FROM
    TblSayacOkumalari
GROUP BY
    CONVERT(NVARCHAR, YEAR(okuma_tarihi)) + 'T1', YEAR(okuma_tarihi)

UNION ALL

SELECT
    CONVERT(NVARCHAR, YEAR(okuma_tarihi)) + 'T2' AS sno,
    YEAR(okuma_tarihi) AS Yillar,
    SUM(toplam_kullanim_T2) AS TotalUsageValue, 'T2' AS UsageType
FROM
    TblSayacOkumalari
GROUP BY
    CONVERT(NVARCHAR, YEAR(okuma_tarihi)) + 'T1', YEAR(okuma_tarihi)

UNION ALL

SELECT
    CONVERT(NVARCHAR, YEAR(okuma_tarihi)) + 'T3' AS sno,
    YEAR(okuma_tarihi) AS Yillar,
    SUM(toplam_kullanim_T3) AS TotalUsageValue, 'T3' AS UsageType
FROM
    TblSayacOkumalari
GROUP BY
    CONVERT(NVARCHAR, YEAR(okuma_tarihi)) + 'T1', YEAR(okuma_tarihi)

我想将CONVERT(nvarchar, YEAR(okuma_tarihi)) + 'T1' AS sno 定义为主键,这可能吗?如果可以的话,我该怎么办?

【问题讨论】:

【参考方案1】:

您不能在视图上创建主键。在 SQL Server 中,您可以 create an index on a view 但这与创建主键不同。

如果您向我们提供更多信息,说明您为什么要在视图中添加密钥,也许我们可以提供帮助。

【讨论】:

我从视图中创建了一个模型,并将 sno 手动更改为实体键。当我更新模型时,我也必须将其更改为实体键。这不适合我。 “如果您向我们提供更多信息,说明您为什么要在视图上添加一个键” - 实体框架会抛出一个视图没有主键的警告:Error 6002: The table/view 'mydb.dbo.myview' does not have a primary key defined... @Ivan 以下链接可能对这种情况有所帮助:***.com/a/2715299/1464699 顺便说一句,@KevinAenmey,我也想要外键。我的视图实际上是在扩展(附加一些运行时计算的列)另一个具有外键(复合主键的一部分)的表,所以我希望实体框架能够理解视图具有相同的自然关系到原始表的其他表。看起来自然而简单,但在实际的 EF 中,视图只是将视图视为一组列,不知道特定单元格值引用另一个表这一事实。 @Marco :为避免混淆,不,您不能在视图上创建 PK,即使它是模式绑定的。但是,如果需要,您可以在其上放置一个唯一的聚集索引,这从实际角度来看几乎是相同的,但它的元数据会有所不同(例如,sys.objects 中没有 PK 对象,列sys.indexes 中的 is_primary_key 为 0, ... ),因此某些应用程序(例如某些 ORM 的)将无法识别它以找出键列。..【参考方案2】:

您可能无法创建主键(例如),但如果您的视图基于具有主键的表并且该键包含在视图中,那么主键也将反映在视图中.需要主键的应用程序可以像使用 Lightswitch 一样接受视图。

【讨论】:

我尝试使用相同的@DLallemant,但实际表的主键不能作为主键敌人视图表。【参考方案3】:

这个聚会有点晚了——但这也很好用:

CREATE VIEW [ABC].[View_SomeDataUniqueKey]
AS
SELECT 
CAST(CONCAT(CAST([ID] AS VARCHAR(4)), 
        CAST(ROW_NUMBER() OVER(ORDER BY [ID] ASC) as VARCHAR(4)) 
        )  AS int) AS [UniqueId]
,[ID]
FROM SOME_TABLE JOIN SOME_OTHER_TABLE
GO

在我的情况下,连接导致 [ID] - 主键最多重复 5 次(关联不同的唯一数据) 这样做的好处是可以从每个 UniqueID 中确定原始 ID 有效地 [ID]+RowNumber() = 11, 12, 13, 14, 21, 22, 23, 24 等。 如果您将 RowNumber() 和 [ID] 添加回视图中 - 您可以轻松地从数据中确定您的原始键。 但是 - 这不是应该提交给表的东西,因为我相当确定视图的 RowNumber() 永远不会与基础数据更改可靠地相同,即使使用 OVER(ORDER BY [ID] ASC)尝试帮助它。

示例输出(Select UniqueId, ID, ROWNR, Name from [REF].[View_Systems]):

UniqueId ID ROWNR Name 11 1 1 Amazon A 12 1 2 Amazon B 13 1 3 Amazon C 14 1 4 Amazon D 15 1 5 Amazon E

表1:

[ID] [Name] 1 Amazon

表2:

[ID] [Version] 1 A 1 B 1 C 1 D 1 E

CREATE VIEW [REF].[View_Systems]
AS    
SELECT 
CAST(CONCAT(CAST(TABA.[ID] AS VARCHAR(4)), 
        CAST(ROW_NUMBER() OVER(ORDER BY TABA.[ID] ASC) as VARCHAR(4)) 
        )  AS int) AS [UniqueId]
,TABA.[ID]
,ROW_NUMBER()  OVER(ORDER BY TABA.[ID] ASC) AS ROWNR
,TABA.[Name]  
FROM  [Ref].[Table1] TABA LEFT JOIN [Ref].[Table2] TABB ON TABA.[ID] = TABB.[ID]
GO

【讨论】:

【参考方案4】:

在 SQL Server 查询设计器中创建视图后,我收到错误“表/视图 'dbo.vMyView' 没有定义主键”。我通过在列上使用 ISNULL 来强制实体框架将其用作主键来解决问题。您可能需要重新启动 Visual Studio 才能让警告消失。

CREATE VIEW [dbo].[vMyView]
AS
SELECT ISNULL(Id, -1) AS IdPrimaryKey, Name
FROM  dbo.MyTable

【讨论】:

【参考方案5】:

这对我有用..

选择 ROW_NUMBER() over (order by column_name_of your choice) 作为 pri_key,视图的其他列

【讨论】:

以上是关于用主键创建视图?的主要内容,如果未能解决你的问题,请参考以下文章

在Postgres中的物化视图上创建主键

在 Postgres 的物化视图上创建主键

Django使用主键创建视图

sql如何创建视图?

oracle:物化视图中的主键列

MySQL笔记--- 创建表;插入,修改,删除数据;主键,外键约束;事务;索引;视图;三范式;