Sütunları dinamik olarak nasıl takma adlandırabilirim?


10

Değişken adlandırılmış 20 sütun içeren bir tablo (benim tarafımdan tasarlanmamış) var. Yani, hangi kayıt türüne baktığınıza bağlı olarak, sütunun uygulanabilir adı değişebilir.

Olası sütun adları çok kolay sorgulayabileceğim başka bir tabloda saklanır.

Bu nedenle, gerçekten aradığım sorgu böyle bir şey gider:

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

Açıkçası bu işe yaramıyor, bu yüzden nasıl benzer bir sonuç alabilirim?

' Ben bir sorgu dizesi inşa ve EXECUTEing denedim , ama bu sadece "Komut (lar) başarıyla tamamlandı" döndürür ve bir satır kümesi döndürüyor görünmüyor. Dinamik SQL oluşturmak için yanlış bir sorgu kullandığım ve bu nedenle boş bir dize oluşturduğu ortaya çıkıyor. SQL Server kesinlikle boş dizeyi doğru bir şekilde yürüttü.

Ben sadece sütun adlarını sabit kodlama yerine, bunun için gerekli neden sütun adlarını kullanıcı yapılandırılabilir olduğunu unutmayın.


1
Sorgu dizesini YAZDIRIR, yeni bir sorgu penceresine kopyalar / yapıştırır ve orada çalıştırırsanız ne olur?
DenisT

"Kullanıcı tarafından yapılandırılabilir" yani yüzlerce veya binlerce tip vardır ve / veya takma adlar sık ​​sık değiştirilir mi? Takma adlar oldukça kararlıysa, bir dizi görünüm oluşturmanızı öneririm.
Tüm

@DenisT, Başka bir şeyin de yanlış olduğunu gösteren hiçbir şey çıkarmaz. Öncü için teşekkürler.
Hotchips

@JonofAllTrades Ne yazık ki, oldukça kararlı olmalarına rağmen, kullanıcı yazılımdaki bir şeyi değiştirdiğinde, o şeyin raporlarda da değişmesi gerektiği özelliğinin bir parçasıdır.
Hotchips

@DenisT Dinamik SQL oluşturmak için kullanılan alt sorgularımın yanlış olduğu ve boş kümeler döndürdüğü ortaya çıktı. SQL Server boş bir sorgu döndürdü, bu da başarıyla yürütüldü. YAZDIR komutunu işaret ettiğiniz için teşekkür ederiz.
Hotchips

Yanıtlar:


12

Aşağıdaki kodu deneyin:

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

Bu SELECT deyimini döndürür: SELECT CONVERT(INT, Col1) AS [AccountID],CONVERT(VARCHAR(50), Col2) AS [AccountName],CONVERT(DATE, Col3) AS [AccountOpenDate] FROM #Data WHERE [Type] = 'Account'


Sorunun SQL ile nasıl yapılacağını sorduğu düşünüldüğünde, dinamik SQL kullanmak doğru cevaptır. Ayrıca yapmaya çalıştığım bir şeydi ama yanlış.
Hotchips

Kullanıcı girişini kabul ediyorsanız ve dinamik SQL oluşturmak için kullanıyorsanız, SQL enjeksiyonu ve girişleri dezenfekte etme konusunda gerçekten endişelenmeniz gerektiğini unutmayın. bobby-tables.com
Jonathan Van Matre

@JonathanVanMatre Kesinlikle. Neyse ki, bu sadece dahili kullanım içindir ve tüm girişler uygulama tarafından zaten sterilize edilmiştir.
Hotchips

7

Bu, bir ön uç ekran çözümü için asal geliyor. Sorgu 1, verilerinizi geri çeker, Sorgu 2, ikinci sorgudan üstbilgileri ayarladığınızı görüntülemek için kullandığınız herhangi bir yapıyı oluşturduğunuzda sütun adlarını ve kodunu geri çeker.

Bir Saf SQL Yöntemi mümkün olsa da, dinamik SQL ve kod bakımı bir kabus olacaktır.

Ayrıca muhtemelen aradığınız sp_executesqlve EXECUTE N'Query String'komutunuzun sorununu başarıyla tamamlayabileceği gibi değil .


Katılıyorum ve bunu kesinlikle SSRS'de yapabilirim, ancak şu anda kullandığım diğer raporlama yazılımlarında yapamam.
Hotchips
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.