动态列 - 如何提高性能

时间:2013-07-30 20:25:40

标签: sql sql-server

好的,第二次尝试问题(首先是How to build virtual columns?

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

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

代码围绕四个表格。

前三个(设备,配件,协会)可以看作每个两个列,一个ID和一个名字。

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

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

  • branchID(主键)
  • association ID(int)
  • 父节点种类(association = 1,equipement = 2,accessory = 3)(int)
  • 父节点ID(其他三个表之一中的ID)(int)
  • kid node kind
  • kid node ID

我确实有一些有用的东西,使用视图和函数(函数代码如下)。但是,表现不尽如人意。

我看到三条改进路径:

  • 通过主键和索引进行微调(如果第4桌上没有主键,代码会明显加快 - 我无法解释)
  • 全面回顾第四张桌子背后的设计(我很开心)
  • 用以下内容替换下面的自定义函数!但那可能是什么呢?

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

  • Type = kind
  • Enfant = kid
  • Jumelage =协会
  • Numero = name(oops ...)
  • liens = branches

感谢。

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

1 个答案:

答案 0 :(得分:1)

这为您提供了所需的列表。如果要根据cte的Delimiter字段将值连续化为带有分隔符的长字符串,请参阅此处:Concatenate many rows into a single text string?

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

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