2015-08-28 74 views
1

我对高级数据库查询和存储过程比较陌生,而且我在下面的过程中发现了第三个UPDATE语句,这是IF代码块中的一个语句。问题是我需要向这些帐户添加成员资格号,因此第一次迭代UPDATElp.ID_1添加到我的临时表中,而第二次迭代将lp.ID_2添加到临时表中。第三次迭代需要从原始INSERT语句(其中ident仍应为NULL)中取出其余行,并将ident列与ID_1ID_2连接在一起,因为这些帐户都具有成员资格。存储过程中的SQL IF条件

我已经在IF块中尝试了几个条件,但似乎每次都没有找到解决方案。

USE [database_1] 
GO 

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

ALTER PROCEDURE [dbo].[stored_procedure_1] @acct char(8) 

AS 

WITH X AS 
(
    select distinct st.ship2, t.name, null AS ident 
    from sales_table st 
    INNER JOIN accounts_table t ON st.ship2 = t.acct 
    where st.bill2 = @acct 
) 
SELECT x.ship2 AS s_acct 
     ,x.name 
     ,COALESCE(ident, lp.ID_1 +', '+ lp.ID_1 , lp.ID_2 , lp.ID_2 , '') AS Ident 
FROM X 
LEFT JOIN lp_table lp ON x.ship2 = lp.acct COLLATE Latin1_General_CS_AS 
WHERE COALESCE(ident, lp.ID_2 +', '+ lp.ID_1 , lp.ID_1 , lp.ID_2 , '') <> '' 

select * from X 
where ident is not null 
+1

你有没有尝试删除if语句,只是'UPDATE'语句被调用吗?你有检查身份是否为空,所以它应该做你期望它做的事情。 –

+1

“'拿走剩余的行......并将ident列与ID_1和ID_2连接起来,因为这些帐户都有成员资格。”“不! **不要这样做!**这是一个有缺陷的schema_。如果帐户可以有多个成员资格,则需要单独的表将帐户映射到成员资格。 **绝不**将csv数据放入列中! –

+0

@JohnOdom,如果我删除了'IF'条件,程序将正常运行,而最后一个'UPDATE'没有任何影响。换句话说,就像最后一个'UPDATE'不在那里一样。 – soundwave

回答

2

我觉得这个整个更新和左连接家当可以写在一个单一的查询,而无需任何更新或临时表

;WITH X AS 
(
    select distinct st.ship2, t.name, null AS ident 
    from sales_table st 
    INNER JOIN account_table t ON st.ship2 = t.acct 
    where st.bill2 = @acct 
) 
SELECT x.ship2 AS s_acct 
     ,x.name 
     ,COALESCE(ident, lp.ID_2 +', '+ lp.ID_1 , lp.ID_1 , lp.ID_2 , '') AS Ident 
FROM X 
LEFT JOIN lp_table lp ON x.ship2 = lp.acct COLLATE Latin1_General_CS_AS 
WHERE COALESCE(ident, lp.ID_2 +', '+ lp.ID_1 , lp.ID_1 , lp.ID_2 , '') <> '' 
+0

'X'从哪里来? – soundwave

+0

'X'是CTE'Common Table expression'的名称,可以替代您的案例中的临时表。 –

+0

好的,我喜欢这里,但我不确定如何在存储过程中实现这一点。我得到了错误,'x.ship2'' x.name'无法绑定 – soundwave

0

第二次更新查询将行不通。第一个更新查询是使用lp_table更新所有具有与“acct”相匹配的#temp_table行的标识值。第二个查询正在查看刚刚更新的行集合,只添加了您仅对ident为null的条件更新的条件....但是,在第一步中,您只是确保没有任何值为空。我认为你要做的是确定哪些行没有被第一个查询更新,假设一些ident被更新为Null。我假设ID_1 \ ID_2中的某些数据为空,因为acct列将始终填充数据。如果我的假设是正确的,你可以做到以下几点:

查询更改为:

create table #temp_table 
(
    s_acct char(8) null, 
    name varchar(50) null, 
    ident varchar(10) null 
) 

insert into #temp_table 
select distinct st.ship2, t.name, null 
from sales_table st, account_table t 
where st.bill2 = @acct 
and st.ship2 = t.acct 

update #temp_table 
set ident = COALESCE(lp.ID_1, lp.ID_2, 'BOTH LPS ARE NULL?') 
from lp_table lp 
where #temp_table.s_acct = lp.acct COLLATE Latin1_General_CS_AS 


select * from #temp_table 
where ident is not null 

而且按照M.Ali的回答可以改进,以消除任何临时表使用率,并做到一气呵成。我已经包含了这个完整性。

+0

在第一个'UPDATE'中应该只插入'ID_1',所以对于那些还没有被分配ID_1的帐户,'ident'列仍然是NULL,因此我的第二个'UPDATE'工作正常。第三个“UPDATE”是我感到困惑的地方。 – soundwave