Làm thế nào tôi có thể tự động các cột bí danh?


10

Tôi có một bảng (không phải do tôi thiết kế) có 20 cột được đặt tên khác nhau. Đó là, tùy thuộc vào loại bản ghi bạn đang xem, tên áp dụng của cột có thể thay đổi.

Các tên cột có thể được lưu trữ trong một bảng khác, mà tôi có thể truy vấn rất dễ dàng.

Do đó, truy vấn tôi thực sự đang tìm kiếm một cái gì đó như thế này:

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

Rõ ràng là không hoạt động, vậy làm thế nào tôi có thể nhận được một kết quả tương tự?

' Tôi đã thử xây dựng một chuỗi truy vấn và nhập EXECUTEnó, nhưng nó chỉ trả về "Các lệnh đã hoàn thành thành công" và dường như không trả về một hàng. Hóa ra tôi đã sử dụng một truy vấn không chính xác để xây dựng SQL động và như vậy đã xây dựng một chuỗi rỗng. SQL Server chắc chắn thực hiện đúng chuỗi trống.

Lưu ý rằng lý do tôi cần điều này xảy ra, thay vì chỉ đơn giản là mã hóa cứng các tên cột, là các tên cột có thể định cấu hình được.


1
Điều gì xảy ra nếu bạn IN chuỗi truy vấn, sao chép / dán vào cửa sổ truy vấn mới và thực hiện nó ở đó?
DenisT

"Người dùng có thể định cấu hình" có nghĩa là có hàng trăm hoặc hàng nghìn loại và / hoặc bí danh được thay đổi thường xuyên? Nếu các bí danh khá ổn định, tôi khuyên bạn nên tạo một loạt các chế độ xem.
Jon của tất cả các giao dịch

@DenisT, Nó không xuất ra bất cứ thứ gì, điều này có lẽ chỉ ra điều gì khác cũng sai. Cảm ơn đã dẫn đầu.
Hotchips 17/214

@Jonof ALLTrades Thật không may, mặc dù chúng khá ổn định, nhưng phần lớn thông số kỹ thuật là khi người dùng thay đổi thứ gì đó trong phần mềm, điều đó cũng phải thay đổi trong các báo cáo.
Hotchips 17/214

@DenisT Hóa ra các truy vấn con của tôi được sử dụng để xây dựng SQL động không chính xác và trả về các tập hợp null. Vì vậy, SQL Server đã trả về một truy vấn trống, được thực hiện thành công. Cảm ơn đã chỉ ra lệnh PRINT.
Hotchips 17/214

Câu trả lời:


12

Hãy thử đoạn mã sau:

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

Điều này trả về câu lệnh SELECT: SELECT CONVERT(INT, Col1) AS [AccountID],CONVERT(VARCHAR(50), Col2) AS [AccountName],CONVERT(DATE, Col3) AS [AccountOpenDate] FROM #Data WHERE [Type] = 'Account'


Sử dụng SQL động là câu trả lời đúng, cho rằng câu hỏi đã hỏi cách thực hiện với SQL. Đó cũng là điều tôi đã cố gắng thực hiện, nhưng không chính xác.
Hotchips 17/214

Hãy nhớ rằng nếu bạn chấp nhận đầu vào của người dùng và sử dụng nó để xây dựng SQL động, thì bạn thực sự, thực sự cần phải quan tâm đến việc nhập SQL và vệ sinh đầu vào. bulk-tables.com
Jonathan Van Matre

@JonathanVanMatre Hoàn toàn. May mắn thay, điều này chỉ dành cho sử dụng nội bộ tất cả các đầu vào đã được ứng dụng vệ sinh.
Hotchips

7

Điều này âm thanh chính cho một giải pháp hiển thị kết thúc trước. Truy vấn 1 sẽ lấy lại dữ liệu của bạn, Truy vấn 2 sẽ lấy lại tên cột và mã khi bạn xây dựng cấu trúc nào bạn sử dụng để hiển thị bạn đặt các tiêu đề từ truy vấn thứ hai.

Mặc dù Phương thức SQL thuần túy có thể là SQL động và việc duy trì mã sẽ là một cơn ác mộng.

Ngoài ra, có lẽ bạn đang tìm kiếm sp_executesqlvà không chỉ EXECUTE N'Query String'vì điều đó có thể khắc phục vấn đề lệnh của bạn đã hoàn thành thành công.


Tôi đồng ý và tôi chắc chắn có thể làm điều này trong SSRS, nhưng tôi không thể làm điều đó trong phần mềm báo cáo khác mà tôi đang sử dụng vào lúc này.
Hotchips 17/214
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.