0

OK、質問の 2 回目の試み (1 回目はHow to build virtual columns? )

この種の質問が StackOverflow に適していない場合は、事前にお詫び申し上げます。必要に応じて自由に削除してください。

基本的な質問は、「コンテンツが動的に構築される列を持つ最良の方法は何か」です。

コードは 4 つのテーブルを中心に展開します。

最初の 3 つ (機器、アクセサリ、関連付け) は、それぞれ ID と名前の 2 つの列として見ることができます。

目標は、関連付け名を、関連付けコンポーネントの名前に基づいて動的に構築された名前に置き換えることです。

4 番目の表は、関連付けを示しています。アソシエーションはツリーとして表示され、ツリーの各「ブランチ」はこのテーブルの線として表されます。列は次のとおりです。

  • branchID (主キー)
  • アソシエーション ID (int)
  • 親ノードの種類 (関連付け = 1、装備 = 2、付属品 = 3) (int)
  • 親ノード ID (他の 3 つのテーブルのいずれかの ID) (int)
  • キッドノードの種類
  • キッドノードID

ビューと関数を使用して機能するものがあります(関数コードは次のとおりです)。ただし、パフォーマンスは満足のいくものではありません。

3 つの改善パスが表示されます。

  • 主キーとインデックスによる微調整 (4 番目のテーブルに主キーがない場合、コードは大幅に高速化されます - 私はそれを説明できませんでした)
  • 4番目のテーブルの背後にあるデザインを完全に見直しています(アイデアは自由です)
  • 以下のカスタム関数を...別のものに置き換えます!しかし、それは何でしょうか?

フランス語の名前で申し訳ありません...コピー/貼り付けエラーは翻訳よりも悪いと仮定して、投稿する前にコードを編集しないことにしました

  • タイプ=種類
  • エンファン=子供
  • ジュムラージュ=協会
  • Numero = 名前 (おっと...)
  • 先取特権 = 枝

ありがとう。

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フィールドに基づいて区切り文字を使用して値を長い文字列に連結する場合は、ここを参照してください: 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

さらにサポートが必要な場合は、質問を明確にしてください。

于 2013-07-30T22:06:41.840 に答える