0

好的,第二次尝试这个问题(首先是如何构建虚拟列?

如果这种问题不适合 StackOverflow,请提前道歉。如果需要,请随时将其取下。

基本问题是“拥有动态构建内容的列的最佳方式是什么”。

代码围绕四个表。

前三个(设备、附件、关联)可以看作是两个列,一个 ID 和一个名称。

目标是将关联名称替换为基于关联组件名称动态构建的名称。

第四个表描述了关联。该关联应该被视为一棵树,树的每个“分支”在此表中都表示为一条线。列是:

  • 分支ID(主键)
  • 关联 ID (int)
  • 父节点种类(关联 = 1,设备 = 2,附件 = 3)(int)
  • 父节点 ID(其他三个表之一中的 ID)(int)
  • 孩子节点类型
  • 孩子节点ID

我确实有一些有用的东西,使用视图和函数(函数代码如下)。但是,性能并不令人满意。

我看到了三个改进路径:

  • 通过主键和索引进行细微调整(如果第 4 个表上没有主键,代码会明显更快 - 我无法解释)
  • 全面审查第四张桌子背后的设计(我对想法持开放态度)
  • 用...替换下面的自定义函数!但那会是什么?

对不起法语名字......我选择在发布之前不编辑代码,假设复制/粘贴错误比翻译更糟糕

  • 类型 = 种类
  • 幼儿=小孩
  • Jumelage = 联想
  • 数字 = 名称(哎呀...)
  • 留置权=分支

谢谢。

USE [testDB]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER FUNCTION [dbo].[testjmrFN] 
(
    @JumelageID int
)
RETURNS varchar(max)
AS
BEGIN
    DECLARE @Result varchar(max)

    DECLARE @TypeParent int
    DECLARE @ParentID int
    DECLARE @TypeEnfant int
    DECLARE @EnfantID int
    DECLARE @NumeroEquipement varchar(max)
    DECLARE @NumeroAccessoire varchar(max)

    SET @Result = ''

    DECLARE liens CURSOR LOCAL FOR 
        SELECT l.TypeParent, l.ParentID, l.TypeEnfant, l.EnfantID, e.Numero, a.Numero
        FROM ges_Jumelages_Liens l
        LEFT JOIN ges_Equipements e ON l.EnfantID = e.EquipementID
        LEFT JOIN ges_Accessoires a ON l.EnfantID = a.AccessoireID
        WHERE l.JumelageID = @JumelageID
        ORDER BY LienID

    OPEN liens

    FETCH NEXT FROM liens INTO @TypeParent, @ParentID, @TypeEnfant, @EnfantID, @NumeroEquipement, @NumeroAccessoire
    WHILE @@FETCH_STATUS = 0
    BEGIN
        IF @TypeParent = 1 AND @TypeEnfant = 2
        BEGIN
            IF @Result <> ''
            BEGIN
                SET @Result = @Result + '§'
            END
            SET @Result = @Result + IsNull(@NumeroEquipement,'')
        END

        IF @TypeParent = 2 AND @TypeEnfant = 3
        BEGIN
            IF @Result <> ''
            BEGIN
                SET @Result = @Result + '~'
            END
            SET @Result = @Result + IsNull(@NumeroAccessoire,'')
        END

        FETCH NEXT FROM liens INTO @TypeParent, @ParentID, @TypeEnfant, @EnfantID, @NumeroEquipement, @NumeroAccessoire
    END

    CLOSE liens
    DEALLOCATE liens

    RETURN @Result

END
4

1 回答 1

1

这为您提供了所需的列表。如果您想根据 cte 的字段将值连接成带有分隔符的长字符串Delimiter,请参见此处:将多行连接成单个文本字符串?

use master;
go
with cte (TypeParent,ParentID,TypeEnfant,EnfantID,Numero,Delimiter)
as 
(   select      l.TypeParent
                , l.ParentID
                , l.TypeEnfant
                , l.EnfantID
                , e.Numero
                , '§'           as Delimiter
    from        dbo.ges_Jumelages_Liens as l
    join        dbo.ges_Equipements as e 
    on          l.EnfantID = e.EquipmentID
    where       l.TypeParent = 1
    and         l.TypeEnfant = 2
    union all
    select      l.TypeParent
                , l.ParentID
                , l.TypeEnfant
                , l.EnfantID
                , a.Numero
                ,'~'            as Delimiter
    from        dbo.ges_Jumelages_Liens as l
    join        dbo.ges_Accessoires as a 
    on          l.EnfantID = a.EquipmentID 
    where       l.TypeParent = 2
    and         l.TypeEnfant = 3 
)
select          *
from            cte

如果您需要进一步的帮助,请澄清您的问题。

于 2013-07-30T22:06:41.840 回答