2015-08-28 71 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