2013-07-30 49 views
0

OK,在這個問題(首先是How to build virtual columns?動態列 - 如何提高性能

道歉提前如果這種問題是不適合初學者StackOverflow的第二次嘗試。如有需要,請隨時取下。

最基本的問題是「什麼是動態構建內容列的最佳方式」。

代碼圍繞着四個表格。

前三個(設備,配件,關聯)可以被看作是兩個colums,一個是ID和一個名稱。

目標是用基於關聯組件名稱動態構建的名稱替換關聯名稱。

第四張表格描述了關聯。該關聯應該被看作一棵樹,樹的每個「分支」在這個表中被表示爲一條線。列有:

  • branchID(主鍵)
  • 關聯ID(INT)
  • 父節點種類(關聯= 1,設備公司= 2,附件= 3)(INT)
  • 父節點ID (在其他三個表的一個ID)(INT)
  • 孩子節點樣
  • 孩子節點ID

我做有一些工作,使用視圖和函數(函數代碼如下)。但是,表現並不理想。

我看到三個改進路徑:

    通過主鍵和索引(代碼顯著更快,如果存在4號表上沒有主鍵 - 我一直沒能解釋)
  • 小幅調整
  • 全面審查第四張桌子後面的設計(我願意接受創意)
  • 用下面的自定義函數代替...別的東西!但那可能是什麼?

很抱歉的法國名字......我選擇不編輯發佈前的代碼,假設複製/粘貼誤差比翻譯

  • 類型糟糕=樣
  • 朗方=小子
  • Jumelage =協會
  • NÚMERO=名稱(哎呀...)
  • 留置權=分支

謝謝。

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 
+0

http://msdn.microsoft.com/en-us/library/bb677290%28v=sql.100%29.aspx – Anon

+0

您是否試圖concatonate值到長字符串,也?你想要的輸出是什麼? –

+0

@jmr:提供樣本輸入和輸出。 –

回答

1

這給你你需要的清單。如果您想要將其值concatonate成一個長字符串基於熱膨脹係數的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 

如果您需要進一步的幫助,請澄清你的問題。

+0

謝謝你花時間。我實際上通過在MgmtConsole中禁用「使用實際執行計劃」選項來修復緩慢(我仍在調試它) - 但是我只是在實現您的方法後才發現這一點。 – jmr

+0

關於如何將多行組合成單一行的另一個優秀閱讀:https://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/ – jmr