列を動的にエイリアスするにはどうすればよいですか?


10

可変名の列が20あるテーブル(私が設計したものではない)があります。つまり、表示しているレコードのタイプに応じて、該当する列の名前が変わる可能性があります。

可能な列名は別のテーブルに格納されているため、非常に簡単にクエリできます。

したがって、私が本当に探しているクエリは次のようになります。

SELECT Col1 AS (SELECT ColName FROM Names WHERE ColNum = 1 and Type = @Type),
       Col2 AS (SELECT ColName FROM Names WHERE ColNum = 2 and Type = @Type)
FROM   Tbl1 
WHERE  Type = @Type

明らかにそれはうまくいかないので、どうすれば同様の結果を得ることができますか?

' クエリ文字列を作成してEXECUTEing しようとしましたが、「Command(s)Completed Successfully」が返され、行セットが返されないようです。 不正なクエリを使用して動的SQLを作成していたため、空の文字列が作成されたことがわかりました。SQL Serverは空の文字列を正しく実行しました。

列名を単にハードコーディングするのではなく、これを実行する必要がある理由は、列名がユーザーが構成できるためです。


1
クエリ文字列を印刷し、新しいクエリウィンドウにコピーして貼り付け、そこで実行するとどうなりますか?
DenisT 2014

「ユーザー設定可能」とは、数百または数千のタイプ、および/または頻繁に変更されるエイリアスがあることを意味しますか?エイリアスがかなり安定している場合は、一連のビューを作成することをお勧めします。
Jon of All Trades

@DenisT、それは何も出力しません。おそらく他の何かも間違っていることを示しています。リードをありがとう。
Hotchips 14

@JonofAllTrades残念ながら、それらはかなり安定していますが、ユーザーがソフトウェアで何かを変更すると、そのこともレポートで変更する必要があるというのが仕様の大部分です。
Hotchips 2014

@DenisT動的SQLを構築するために使用した私のサブクエリが正しくなく、nullセットを返したことがわかりました。そのため、SQL Serverは空のクエリを返し、正常に実行されました。PRINTコマンドを指摘していただきありがとうございます。
Hotchips 2014

回答:


12

次のコードを試してください:

CREATE TABLE #Names
(
    [Type] VARCHAR(50),
    ColNum SMALLINT,
    ColName VARCHAR(50),
    ColDataType VARCHAR(20)
)

INSERT  INTO #Names VALUES
('Customer', 1, 'CustomerID', 'INT'),
('Customer', 2, 'CustomerName', 'VARCHAR(50)'),
('Customer', 3, 'CustomerJoinDate', 'DATE'),
('Customer', 4, 'CustomerBirthDate', 'DATE'),
('Account', 1, 'AccountID', 'INT'),
('Account', 2, 'AccountName', 'VARCHAR(50)'),
('Account', 3, 'AccountOpenDate', 'DATE'),
('CustomerAccount', 1, 'CustomerID', 'INT'),
('CustomerAccount', 2, 'AccountID', 'INT'),
('CustomerAccount', 3, 'RelationshipSequence', 'TINYINT')


CREATE TABLE #Data
(
    [Type] VARCHAR(50),
    Col1 VARCHAR(50),
    Col2 VARCHAR(50),
    Col3 VARCHAR(50),
    Col4 VARCHAR(50),
    Col5 VARCHAR(50),
    Col6 VARCHAR(50),
    Col7 VARCHAR(50)
)

INSERT  INTO #Data VALUES
('Customer', '1', 'Mr John Smith', '2005-05-20', '1980-11-15', NULL, NULL, NULL),
('Customer', '2', 'Mrs Hayley Jones', '2009-10-10', '1973-04-03', NULL, NULL, NULL),
('Customer', '3', 'ACME Manufacturing Ltd', '2012-12-01', NULL, NULL, NULL, NULL),
('Customer', '4', 'Mr Michael Crocker', '2014-01-13', '1957-01-23', NULL, NULL, NULL),
('Account', '1', 'Smith-Jones Cheque Acct', '2005-05-25', NULL, NULL, NULL, NULL),
('Account', '2', 'ACME Business Acct', '2012-12-01', NULL, NULL, NULL, NULL),
('Account', '3', 'ACME Social Club', '2013-02-10', NULL, NULL, NULL, NULL),
('Account', '4', 'Crocker Tipping Fund', '2014-01-14', NULL, NULL, NULL, NULL),
('CustomerAccount', '1', '1', '1', NULL, NULL, NULL, NULL),
('CustomerAccount', '2', '1', '2', NULL, NULL, NULL, NULL),
('CustomerAccount', '2', '3', '2', NULL, NULL, NULL, NULL),
('CustomerAccount', '3', '2', '1', NULL, NULL, NULL, NULL),
('CustomerAccount', '3', '3', '1', NULL, NULL, NULL, NULL),
('CustomerAccount', '4', '2', '2', NULL, NULL, NULL, NULL),
('CustomerAccount', '4', '4', '1', NULL, NULL, NULL, NULL)


DECLARE @Type VARCHAR(50) = 'Account' -- Or Customer, or CustomerAccount

DECLARE @SQLText NVARCHAR(MAX) = ''

SELECT  @SQLText += 'SELECT '

SELECT  @SQLText += ( -- Add in column list, with dynamic column names.
                SELECT  'CONVERT(' + ColDataType + ', Col' + CONVERT(VARCHAR, ColNum) + ') AS [' + ColName + '],'
                FROM    #Names
                WHERE   [Type] = @Type FOR XML PATH('')
            )

SELECT  @SQLText = LEFT(@SQLText, LEN(@SQLText) - 1) + ' ' -- Remove trailing comma

SELECT  @SQLText += 'FROM #Data WHERE [Type] = ''' + @Type + ''''

PRINT   @SQLText
EXEC    sp_executesql @SQLText

これはSELECTステートメントを返します。 SELECT CONVERT(INT, Col1) AS [AccountID],CONVERT(VARCHAR(50), Col2) AS [AccountName],CONVERT(DATE, Col3) AS [AccountOpenDate] FROM #Data WHERE [Type] = 'Account'


動的SQLの使用は、SQLでそれを行う方法を質問する質問を考えると、正しい答えです。それも私がやろうとしたことでしたが、間違っていました。
Hotchips 14

ユーザー入力を受け入れ、それを使用して動的SQLを構築する場合は、SQLインジェクションと入力のサニタイズについて本当に考慮する必要があることに注意してください。bobby-tables.com
Jonathan Van Matre

@JonathanVanMatre絶対に。幸いなことに、これは内部使用のみであり、すべての入力はアプリによって既にサニタイズされています。
Hotchips 2014

7

これは、フロントエンドディスプレイソリューションに最適です。クエリ1はデータをプルし、クエリ2は列名をプルバックし、2番目のクエリからのヘッダーの設定を表示するために使用する構造を構築するときにコード内でコードをプルします。

純粋なSQLメソッドは可能かもしれませんが、動的SQLになるため、コードの保守は悪夢になります。

また、おそらくあなたが探しているsp_executesqlだけでなくEXECUTE N'Query String'、コマンドの問題が正常に完了したことを修正する可能性もあります。


私は同意し、SSRSでこれを確実に実行できますが、現在使用している他のレポートソフトウェアでは実行できません。
Hotchips 14
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.