2016-04-25 92 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

相关问题