-1

如何Dynamicaly列目前,我有以下查询:在UNPIVOT操作

WITH History AS (
    SELECT 
     kz.*, 
     kz.__$operation AS operation, 
     map.tran_begin_time as beginT, 
     map.tran_end_time as endT 
    FROM cdc.fn_cdc_get_all_changes_dbo_EXT_GeolObject_KategZalezh(sys.fn_cdc_get_min_lsn('dbo_EXT_GeolObject_KategZalezh'), sys.fn_cdc_get_max_lsn(), 'all') AS kz 
     INNER JOIN [cdc].[lsn_time_mapping] map 
    ON kz.[__$start_lsn] = map.start_lsn 
    where kz.GUID_BalanceHC_Zalezh = 'DDA9AB3A-A0AF-4623-9362-0000C8C83D63' 
), 
UnpivotedValues AS(
    SELECT guid, GUID_another, field, val, operation, beginT, endT 
    FROM History 
     UNPIVOT ([val] FOR field IN 
     (
      area, 
      oilwidthmin, 
      oilwidthmax, 
      efectivwidthmin, 
      efectivwidthmax, 
      etc... 
     ))t 
), 
UnpivotedWithLastValue AS (
    SELECT 
     *, 
     --Use LAG() to get the last value for the same field 
     LAG(val, 1) OVER (PARTITION BY guid, GUID_another, field ORDER BY BeginT) LastVal 
    FROM UnpivotedValues 
) 
SELECT * FROM UnpivotedWithLastValue WHERE val <> LastVal OR LastVal IS NULL ORDER BY guid 

该查询返回更改后的值对于具有CDC(更改数据捕获)功能的一个表。 我想创建一个存储过程,该过程接收未转义的列,并将cdc函数(例如cdc.fn_cdc_get_all _...)作为参数并返回结果集。

此表格的结果必须加入一个报告中。

在我的情况下,参数1是cdc.fn_cdc_get_all_changes_dbo_EXT_GeolObject_KategZalezh(sys.fn_cdc_get_min_lsn('dbo_EXT_GeolObject_KategZalezh'), sys.fn_cdc_get_max_lsn(), 'all')。这是CDC的功能。 我应该如何在结果中发送我想要的字段列表?字符串怎么样? 另外,有没有办法做到没有动态SQL?动态SQL它不是更好的性能解决方案。

+0

你能提供您所期望的存储过程来接收(参数)和返回(数据结果集)的概述。 例如该程序是否应该一次在多个CDC表格上工作(即接收表格列表作为参数),还是期望每个CDC表格一次调用该程序? – dybzon

回答

1

正如您所知,SQL Server是按设计声明的,并且不支持宏替换。

UNPIVOT显然更具性能,但这里有一个简化的UNPIVOT示例,它不需要动态SQL,只需要一点XML。

让我们假设你的表/结果是这样的:

enter image description here

您可能注意到,我只有我们只指定键字段最终在排除

Declare @YourData table (ID int,Active bit,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50),Salary decimal(10,2)) 
Insert into @YourData values 
(1,1,'John','Smith','[email protected]',85600), 
(2,0,'Jane','Doe' ,'[email protected]',83200) 

;with cte as (
    -- Replace with your Complex Query 
    Select * from @YourData 
) 
Select A.ID 
     ,A.Active 
     ,C.* 
From cte A 
Cross Apply (Select XMLData=cast((Select A.* for XML RAW) as xml)) B 
Cross Apply (
       Select Item = attr.value('local-name(.)','varchar(100)') 
         ,Value = attr.value('.','varchar(max)') 
       From XMLData.nodes('/row') C1(n) 
       Cross Apply C1.n.nodes('./@*') C2(attr) 
       Where attr.value('local-name(.)','varchar(100)') not in ('ID','Active') 
      ) C 

返回

enter image description here