2016-04-25 56 views
0

我想知道是否有人可以幫助我與下面的任何或全部代碼。我已經完成了它的工作,但對我來說似乎效率低下,可能比最優慢。是否有更高效/優雅的方式來編寫我的代碼?

這個代碼在首位的必要性一些基本的背景:

我有不包括相應的發票號發貨記錄的表。我已經瀏覽了所有桌子,並繼續這樣做。事實上,只有今天早上,我發現如果已經產生裝箱單,我可以通過裝箱單ID將裝運臺連接到裝箱單並從那裏獲取發票號碼。然而,如果沒有這種聯繫,我不得不猜測。在大多數情況下,這不是非常困難,因爲發票表的號碼,行和發行版可以匹配。但是,如果有多個貨件用於號碼,行和發行(例如,當一條線部分發貨時),那麼可以有多個答案,其中只有一個是正確的。我的部分幫助是通過發貨表中的一列來說明該號碼,行號和發行日期的順序是什麼,但仍然有些情況下我用於「猜測」的過程可能有些模棱兩可。

我的程序是做什麼的。首先,它會創建一個包含發票號碼的數據表,如果有包裹單連接它的話。

接下來,它會將所有數據轉儲到第二個表中,這次使用 - 僅當發票在第一個表中爲NULL時 - 基於對所有運輸記錄進行分區的發票號的「猜測」數字,行,發佈,日期順序和日期,然後將其與發票表的相同類型的東西進行比較,並嘗試按日期排列所有內容。

最後,它通過該表解析並找到最後一個空值,並將它們與該號碼,行和釋放的任何發票的第一條記錄進行基本匹配。

這兩個猜測都添加了字符來表明他們實際上是在猜測。

IF OBJECT_ID('tempdb..#cosTAble') IS NOT NULL 
DROP TABLE #cosTable 

DECLARE @cosTable2 TABLE (
    ID    INT IDENTITY 
    ,co_num   CoNumType 
    ,co_line  CoLineType 
    ,co_release  CoReleaseType 
    ,date_seq  DateSeqType 
    ,ship_date  DateType 
    ,inv_num  NVARCHAR(14) 
    ) 

DECLARE 
    @co_num_ck  CoNumType 
    ,@co_line_ck CoLineType 
    ,@co_release_ck CoReleaseType 

DECLARE @Counter1 INT = 0 

SELECT cos.co_num, cos.co_line, cos.co_release, cos.date_seq, cos.ship_date, cos.qty_invoiced, pck.inv_num 
    INTO #cosTable 
    FROM co_ship cos 
     LEFT JOIN pckitem pck 
      ON cos.pack_num = pck.pack_num 
      AND cos.co_num = pck.co_num 
      AND cos.co_line = pck.co_line 
      AND cos.co_release = pck.co_release 

;WITH cos_Order 
    AS(
     SELECT co_num, co_line, co_release, qty_invoiced, date_seq, ship_date, ROW_NUMBER() OVER (PARTITION BY co_num, co_line, co_release ORDER BY ship_date) AS cosrow 
     FROM co_ship 
     WHERE qty_invoiced > 0 
    ), 

invi_Order 
    AS(
     SELECT inv_num, co_num, co_line, co_release, ROW_NUMBER() OVER (PARTITION BY co_num, co_line, co_release ORDER BY RecordDate) AS invirow 
     FROM inv_item 
     WHERE qty_invoiced > 0 
    ), 

cos_invi 
    AS(
     SELECT cosO.*, inviO.inv_num 
     FROM cos_Order cosO 
      LEFT JOIN invi_Order inviO 
       ON cosO.co_num = inviO.co_num AND cosO.co_line = inviO.co_line AND cosO.cosrow = inviO.invirow) 

INSERT INTO @cosTable2 
SELECT cosT.co_num, cosT.co_line, cosT.co_release, cosT.date_seq, cosT.ship_date, COALESCE(cosT.inv_num,'*'+cosi.inv_num) AS inv_num 
    FROM #cosTable cosT 
    LEFT JOIN cos_invi cosi 
     ON cosT.co_num = cosi.co_num 
     AND cosT.co_line = cosi.co_line 
     AND cosT.co_release = cosi.co_release 
     AND cosT.date_seq = cosi.date_seq 
     AND cosT.ship_date = cosi.ship_date 



WHILE @Counter1 < (SELECT MAX(ID) FROM @cosTable2) BEGIN 
    SET @Counter1 += 1 
    SET @co_num_ck = (SELECT co_num FROM @cosTable2 WHERE ID = @Counter1) 
    SET @co_line_ck = (SELECT co_line FROM @cosTable2 WHERE ID = @Counter1) 
    SET @co_release_ck = (SELECT co_release FROM @cosTable2 WHERE ID = @Counter1) 
    IF EXISTS (SELECT * FROM @cosTable2 WHERE ID = @Counter1 AND inv_num IS NULL) 
     UPDATE @cosTable2 
      SET inv_num = '^' + (SELECT TOP 1 inv_num FROM @cosTable2 WHERE 
          @co_num_ck = co_num AND 
          @co_line_ck = co_line AND 
          @co_release_ck = co_release) 
      WHERE ID = @Counter1 AND inv_num IS NULL 
    END 

SELECT * FROM @cosTable2 
ORDER BY co_num, co_line, co_release, date_seq, ship_date 

回答

1

在我看來,你正在努力解決一個不應該存在的問題。您所描述的是一個不幸的常見情況,即隨着業務的增長,一個流程不斷髮展而沒有意圖和具體的方向,這使得數據提取幾乎不可能實現自動化。您非常需要一套政策和程序 - 對於(非常粗糙和簡單)的示例: 1:在生成裝箱單之前必須存在訂單。 2:裝箱單必須存在之前可以生成發票。
3:使用裝箱單和訂單中的數據創建發票(請求的內容,拾取的內容,我們的賬單) - 再次,這僅僅是一個粗略的例子來說明這個想法。 所有的數據必須在正確的時間輸入或有人沒有完成他們的工作。 當IT數據不存在時,IT部門的典型技能並不在於準確一致地提供管理良好的數據。

+0

我會懷疑他的問題是不正確使用FK約束和數據定義的直接結果。如果發票的裝箱單中有FK,並且裝箱單ID是必需的,則只有在與裝箱單相關後才能創建發票。他應該試圖解決爲什麼這種情況不存在的問題。然而,即便如此,您仍然需要識別這些目前搞砸的記錄並修復它們。但那是一次性修復。 – HLGEM

2

你現在處境不好 - 正如@ craig.white和@HLGEM所建議的,你已經繼承了一些沒有足夠約束的東西來使數據正確或安全......現在你必須「合成」它。我得到的猜測是你能做的最好的,你可以,至少讓你的猜測合理的表現明智。

之後,您應該大聲尖叫以獲得一些時間來修復數據庫 - 應用所需的約束以防止數據的進一步混淆。

性能方面,while循環是一場災難。你會好起來的......像有一個更新語句替換是全亂了:

update c0 
set inv_nbr = '^' + c1.inv_nbr 
from 
    @cosTable2 c0 
    left outer join 
    (
    select 
     co_num, 
     co_line, 
     co_release, 
     inv_nbr 
    from 
     @cosTable2 
    where 
     inv_nbr is not null 
    group by 
     co_num, 
     co_line, 
     co_release, 
     inv_nbr   
) as c1 
    on 
    c0.co_num = c1.co_num and 
    c0.co_line = c1.co_line and 
    c0.co_release = c1.co_release 
where 
    c0.inv_num is null 

...這確實循環做同樣的事情,只是在單個語句。

+0

這就是我所需要的,謝謝。我一直在努力處理update語句,總是插入相同的值,這是我無法工作的部分。我也很欣賞每個人的評論和支持,確認我不是瘋了,我不應該這樣做。希望我能在將來改進它。 – DaveX

+0

@DaveX,祝你好運 - 我們中的很多人都在你的鞋子裏 – Clay

+0

我只是用完全不同的程序來調整這個相同的結構。像魅力一樣工作。非常感激。 – DaveX

相關問題