2017-01-02 76 views
1

我有以下測試查詢我需要使動態。SQL Server - 使用JSON返回列名稱

基本上,一個存儲過程將被傳遞@json,並且它需要返回在該變量中傳遞的列名。

這是可能的,我該怎麼辦?

declare @json varchar(max) 

set @json = '["FirstName", "LastName","DOB"]'; 

select * 
from OPENJSON(@json) 

select 
FirstName, 
LastName, 
DOB 
from Client 

我有這個的作品,但不知道它是否是一個很好的選擇,是否有更好的方法

declare @json varchar(max) 
declare @columnames varchar (200) 
declare @sqlquery nvarchar(200) 

set @json = '["FirstName", "LastName","DOB"]'; 
set @columnames ='' 

select @columnames = 
    case when @columnames = '' 
    then value 
    else @columnames + coalesce(',' + value, '') 
    end 
    from OPENJSON(@json) 

set @sqlquery = 'select ' + @columnames + ' from Client' 

EXEC SP_EXECUTESQL @sqlquery 

基本上@json變量可以包含一個或多個或所有的低於領域和超過時間更多。

set @json = '["FirstName", "LastName","DOB","DrugName,"Age","AgeGroup","Overdose","VerificationCode","Gender"]'; 
+0

最好的方法是解析應用程序中的數據。關於sqlserver的最佳做法是創建具有反序列化的CLR TVL函數 - 這個函數具有非確定性,並且您必須在您的應用程序中使用泛型代碼。在這個json示例字符串中,您可以使用字符串,但可以有更復雜的字符串包含轉義字符。結論 - 解析app中的數據。第二個選項 - 使用序列化和標量CLR到xml並在sqlserver上使用xquery。例如:http://www.sqlservercentral.com/articles/SQLCLR/74160/ – Deadsheep39

+0

哇,這是一些複雜的東西@ Deadsheep39。我需要這樣做的原因是,這是一個我正在構建的自定義報告,前端用戶需要能夠選擇他們希望在報告中返回的列。 – Philip

+0

我不知道它必須像@ Deadshepp39所暗示的那樣複雜。當然,我也會建議在應用程序端解析。這是返回所有列,並決定應用程序端顯示的內容。有更多的數據流量,但動態SQL(尤其是SQL注入)出錯的可能性更小。您擁有的動態SQL是唯一的解決方案,但您有理由懷疑它。這是最好的避免。當SQL Server始終確切地知道哪些列正在返回時,SQL Server效果最佳。 –

回答

0

在這種情況下(您的json字符串只包含包含列名的標題)並且僅用於列選擇,因此很容易。如果你想從json字符串中獲取值,則要困難得多。

變體1:使用系統表來驗證您的輸入並獲取列名。

declare @json varchar(800) = '["FirstName", "LastName", "DOB","DrugName,"Age","AgeGroup", "Overdose","VerificationCode","Gender"]', 
@columnames varchar(800) 

select @columnames = isnull(@sql + ', ', name) + name 
from (
    select name, '"' + name + '"' name_quoted 
    from sys.columns c 
    where object_id('dbo.Client') = object_id) t 
where @json like '%' + name_quoted + '%' 

print @columnames 
exec ('select ' + @columnames + ' from dbo.Client') 

變2:處理字符串。

declare @json varchar(800) = '["FirstName", "LastName","DOB","DrugName,"Age","AgeGroup","Overdose","VerificationCode","Gender"]'; 
declare @sql varchar(max) = replace(substring(@json, 2, len(@json) - 2), '"','') 
print @sql 
exec ('select ' + @sql + ' from dbo.Client') 
+0

謝謝@ Deadsheep39 - 欣賞:) – Philip