2016-11-06 12 views
0

パラメータに基づいて列を選択するSQL Serverストアドプロシージャを作成できます。選択順序は別のパラメータに基づいている必要があります。特定の順序でアクティブな列のみを選択するSQL Serverストアドプロシージャ

たとえば、私はいくつかの列(名前、日付、Addr1、Addr2、Addr3)を持つテーブルtblStagingを持っています。このテーブルを使用して、ストアドプロシージャを使用してXMLを作成します。ストアドプロシージャは、単にこの表から列を選択し、XML構文でそれらを表示するであろう、何かのように:

SELECT 
    Name, date, Addr1, Addr2, Addr3 
FROM 
    tblStaging 
FOR XML RAW ('TRAN'), ROOT ('SEPA'), ELEMENTS; 

は今、私は、ユーザーのパスに2つのパラメータ、すなわち「アクティブ」をさせることで、このストアドプロシージャが設定可能なようにしたいですフラグと '注文'。アクティブ:1または0は、フィールドがXMLスキーマで選択されるかどうかを決定します。注文:1,2,3,4 ..フィールドの選択順序を決定します。 'Name'がActive = 1とOrder = 2に設定されている場合、選択されますが、XMLでは1番目の要素ではなく2番目の要素として選択されます。

これを達成する最もよい方法は何ですか?テーブルごとに10個のカラム(= 20個のパラメータ)があれば、カラムごとに2つのパラメータを持ち、それぞれに値を渡すように頼むべきかどうかは分かりません。

ありがとうございます!

+0

は、より多くの情報が必要。データの目的は何ですか?あなたはすべての結果を必要としますか?フレームワークレベルで注文を処理できない理由はありますか? –

答えて

1

私はあなたのための作業コードを書いています。テストされていないSQLインジェクションの対象となるプロダクションシステムで使用する前に、さらに開発することをお勧めします。

@OrderBy:SQLで許可されたとして、あなたはまた、

@Columnsを(order by 1 ASCが動作します)序を使用することができます:あなたは

さらなる開発は、テーブル名に別の変数を追加することができ序や列名を使用することのいずれか、例えば。

CREATE PROCEDURE dbo.Sample_Procedure 
    @Orderby nvarchar(100) = 'Name Asc', 
    @Columns nvarchar(100) = '1,2,3,Name' 
AS 
DECLARE @SQLString nvarchar(500) 
DECLARE @UsedColumns nvarchar(500) 
DECLARE @X xml 

/* 
    Using string manipulation and covert to transform @Columns to xml, 
    so 1,2,3 becomes: <root><s>1</s><s>2</s><s>2</s></root> and then 
    converted to XML so we can select from it as if it was a table. 
    if you have SQL 2016 it's possible to replace it with STRING_SPLIT 
*/ 
SELECT @X = CONVERT(xml,' <root> <s>' + REPLACE(@Columns,',','</s> <s>') + '</s> </root> ') 


DECLARE @ColsTab as TABLE (Col nvarchar(100)) 
/*This part "shreds" the xml above into the variable table @ColsTab. 
    we need it for the `IN' operator later. 
*/ 
INSERT into @ColsTab (col) 
SELECT T.c.value('.','varchar(20)') FROM @X.nodes('/root/s') T(c) 


SET @UsedColumns = STUFF( (SELECT ',' + COLUMN_NAME 
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME='tblStaging' 
     and (COLUMN_NAME in (Select Col from @ColsTab) 
      or ORDINAL_POSITION in (Select iif(IsNumeric(Col)=1,Col,Null) from @ColsTab) 
      ) 
       FOR XML PATH('')), 
      1, 1, '') 



SET @SQLString = 'Select '+ @UsedColumns +' 
from tblStaging 
order by '[email protected]+' 
FOR XML RAW (''TRAN''), ROOT (''SEPA''), ELEMENTS'; 

EXECUTE sp_executesql @SQLString 

RETURN 

同じクエリ、今回動的問合せは、出力列の順序を設定している:

CREATE PROCEDURE dbo.Sample_Procedure2 
    @Orderby nvarchar(100) = 'Name Asc', 
    @Columns nvarchar(100) = '2,3,Name' 
AS 
DECLARE @SQLString nvarchar(500) 
DECLARE @UsedColumns nvarchar(500) 
DECLARE @X xml 

/* 
    Using string manipulation and covert to transform @Columns to xml, 
    so 1,2,3 becomes: <root><s>1</s><s>2</s><s>2</s></root> and then 
    converted to XML so we can select from it as if it was a table. 
    if you have SQL 2016 it's possible to replace it with STRING_SPLIT 
*/ 
SELECT @X = CONVERT(xml,' <root> <s>' + REPLACE(@Columns,',','</s> <s>') + '</s> </root> ') 


DECLARE @ColsTab as TABLE (Col nvarchar(100)) 
/*This part "shreds" the xml above into the variable table @ColsTab. 
    we need it for the `IN' operator later. 
*/ 
INSERT into @ColsTab (col) 
SELECT T.c.value('.','varchar(20)') FROM @X.nodes('/root/s') T(c) 


/* This version usues left join to assume the same order of 
    columns as specified in the input field @Columns 
    be mindful not to specify the same field twice 
*/ 
SET @UsedColumns = STUFF( (
    SELECT  ',' + i.COLUMN_NAME 
    FROM  @ColsTab as c 
    LEFT JOIN INFORMATION_SCHEMA.COLUMNS as i 
     ON  i.COLUMN_NAME = Col 
      OR ORDINAL_POSITION = iif(IsNumeric(Col)=1,Col,Null) 
    WHERE  TABLE_NAME='tblStaging' 
     AND  COLUMN_NAME is not null 
       FOR XML PATH('')), 
       1, 1, '') 



SET @SQLString = 'Select '+ @UsedColumns +' 
from tblStaging 
order by '[email protected]+' 
FOR XML RAW (''TRAN''), ROOT (''SEPA''), ELEMENTS'; 

EXECUTE sp_executesql @SQLString 

RETURN 
+0

こんにちは@UV、それは本当に役に立ちます!私はスクリプトを実行しようとしましたが、 '@Columns 'で指定された列で完全にXMLを作成します。しかし、 '@ Columns'変数で指定された順序ではなく、テーブルスキーマに表示されるように列を順序付けしているようです。例えば。 '@Columns = '4,1,2,3''と設定しましたが、XMLの結果はまだ1,2,3,4の順番で表示されています。 '@ Orderby'変数は' '1 Asc ''に設定されました。どこが間違っているのか分かりません。これで助けてくれますか? –

+0

また、私はコードのビットを理解することはできますが、すべてを理解することはできません。 '@X'または' @ UserColumns'がどのように割り当てられているかを示します。どのように動作しているかを説明することができれば素晴らしいでしょう。私は、必要に応じてコードを変更したり、必要に応じて条件を追加する立場にいます。 –

+0

こんにちはアッシャー、 '@ OrderBy'はソートのためのもので、クエリの' Order By'セクションに直接使われています。私はあなたのためのコードにいくつかのコメントを追加します:)乾杯 - Yuval –

関連する問題