if my tables are not clear,我试图找到普通表和审计表之间的差异。
Iam_audit:
A_n L_name A_status
---------------------------
1 abc AL
2 def AC
荫
a_n audit_field field_after
-------------------------------------
1 L_name abd
1 a_status AL
2 L_name def
2 a_status AD
预期:
a_n field_after audit_field a_n name
--------------------------------------------
1 abc l_name 1 abd
a_n field_after audit_field a_n name
2 AC a_status 2 AD
当前
a_n field_after audit_field a_n name
-----------------------------------------------
1 abc l_name 1 l_name
2 def l_name 1 l_name
a_n field_after audit_field a_n name
1 AL a_status 1 a_status
2 AC a_status 2 a_status
问题在于iam_audit
它是一个列名,而在Iam
中它是一个列本身。我有更多的列来比较使用光标。有解决方案吗
(查看附上的图片以获得清晰的图片)
declare @af varchar(500)
set @af = 'L_Name,A_Status'
declare @pa varchar(50)
declare audit_cur cursor for
select ltrim(rtrim(Parameter)) 'Audit_FLD'
from phngeneral.dbo.fcn_TheDelimiterEliminator(@af,',')
OPEN audit_cur
FETCH NEXT FROM audit_cur into @pa
WHILE @@FETCH_STATUS = 0
BEGIN
select *
from
(select a.A_n, a.field_after, audit_field
from Db.iam_audit a
where a.Audit_Field = @af) i
left join
(select distinct a_n, @pa as name
from Db.iam) il on i.a_n = il.a_n
where
i.audittable_field_after <> il.name
order by
1 desc
FETCH NEXT FROM audit_cur into @pa
END
CLOSE audit_cur
DEALLOCATE audit_cur
答案 0 :(得分:1)
我也认为你可以像HABO所说的那样使用动态SQL。
您需要生成并执行以下查询
SELECT a.A_n,i.audit_field,a.L_name field_value,i.field_after
FROM Iam_audit a
JOIN Iam i ON i.audit_field='L_name' AND i.A_n=a.A_n AND a.L_name<>i.field_after
SELECT a.A_n,i.audit_field,a.A_status field_value,i.field_after
FROM Iam_audit a
JOIN Iam i ON i.audit_field='A_status' AND i.A_n=a.A_n AND a.A_status<>i.field_after
演示表和数据
create table Iam_audit(A_n int,L_name varchar(10),A_status varchar(10))
insert Iam_audit(A_n,L_name,A_status)values
(1,'abc','AL'),
(2,'def','AC')
create table Iam(a_n int,audit_field varchar(10),field_after varchar(10))
insert Iam(a_n,audit_field,field_after)values
(1,'L_name','abd'),
(1,'a_status','AL'),
(2,'L_name','def'),
(2,'a_status','AD')
最终解决方案
declare @af varchar(500) = 'L_Name,A_Status'
declare @pa varchar(50)
-- I think you can replace it to your cursor version with fcn_TheDelimiterEliminator
declare audit_cur cursor for
select distinct audit_field
from Iam
where concat(',',@af,',') like concat('%,',audit_field,',%')
/*
declare audit_cur cursor for
select ltrim(rtrim(Parameter)) 'Audit_FLD'
from phngeneral.dbo.fcn_TheDelimiterEliminator(@af,',')
*/
OPEN audit_cur
FETCH NEXT FROM audit_cur into @pa
declare @cmd varchar(1000)
WHILE @@FETCH_STATUS = 0
BEGIN
set @cmd=concat('SELECT a.A_n,i.audit_field,a.',@pa,' field_value,i.field_after
FROM Iam_audit a
JOIN Iam i ON i.audit_field=''',@pa,''' AND i.A_n=a.A_n AND a.',@pa,'<>i.field_after')
print @cmd -- for debug
exec(@cmd)
FETCH NEXT FROM audit_cur into @pa
END
CLOSE audit_cur
DEALLOCATE audit_cur
不要忘记在任何地方添加Db.
前缀。
我认为您在示例中混淆了表Iam_audit
和Iam
的名称。也许你需要交换他们的名字。
答案 1 :(得分:0)
这可能听起来很傻。但是我试图再添加一个名为modifeid date的列并尝试获取最后修改日期值,但是我得到&#34;必须声明标量变量@ pa&#39;错误。
create table #Iam_audit(A_n int,L_name varchar(10),A_status varchar(10))
insert #Iam_audit(A_n,L_name,A_status)values
(1,'abc','AL'),
(2,'def','AC')
create table #Iam(a_n int,audit_field varchar(10),field_after varchar(10),[Modified_Date] [datetime])
insert #Iam(a_n,audit_field,field_after,[Modified_Date])values
(1,'L_name','abd','2006-05-10 00:57:44.467'),
(1,'a_status','AL','2005-05-10 00:57:44.467'),
(1,'L_name','abdd','2009-05-10 00:57:44.467'),
(1,'a_status','AL','2009-05-10 00:57:44.467'),
(2,'L_name','def','2005-05-10 00:57:44.467'),
(2,'a_status','AD','2007-05-10 00:57:44.467'),
(2,'L_name','def','2006-05-10 00:57:44.467'),
(2,'a_status','AD','2008-05-10 00:57:44.467')
declare @af varchar(500) = 'L_Name,A_Status'
declare @pa varchar(50)
declare audit_cur cursor for
select distinct audit_field
from #Iam
where concat(',',@af,',') like concat('%,',audit_field,',%')
OPEN audit_cur
FETCH NEXT FROM audit_cur into @pa
declare @cmd varchar(1000)
WHILE @@FETCH_STATUS = 0
BEGIN
set @cmd=concat('SELECT a.A_n,i.audit_field,a.',@pa,' field_value,i.field_after
FROM #Iam_audit a
JOIN (Select a.A_n, a.field_after,audit_field
from #iam a(nolock)
inner join (Select a_n, max(Modified_Date) as maxdate
from #iam a2(nolock)
where a2.Audit_field=@pa
group by a_n
) as aa on aa.a_n = a.a_n and aa.maxdate=a.modified_Date
where a.Audit_Field=@pa ) i
ON i.audit_field=''',@pa,''' AND i.A_n=a.A_n AND a.',@pa,'<>i.field_after')
print @cmd -- for debug
exec(@cmd)
FETCH NEXT FROM audit_cur into @pa
END
CLOSE audit_cur
DEALLOCATE audit_cur