try:
CREATE PROC UP_INV_ZL_New (@DATE1 DATETIME,@Khbh CHAR(10),@Ywy CHAR(10))
AS
BEGIN
    SET NOCOUNT ON
    SET ARITHABORT OFF
    SET ARITHIGNORE ON     DECLARE @ErrNo INT,
            @ErrMsg VARCHAR(255),
            @NKhbh CHAR(10)        DECLARE @InvYs TABLE(客户编号 CHAR(6),
                         出仓日期 DATETIME,
                         出入单号 CHAR(10),
                         金额 DECIMAL(12,3) DEFAULT 0)
    DECLARE @InvSs TABLE(客户编号 CHAR(6),
                         出入单号 CHAR(10),
                         金额 DECIMAL(12,3) DEFAULT 0)
    BEGIN TRAN           INSERT INTO @InvYs
           SELECT 客户编号,max(出仓日期),出入单号,SUM(金额 * 应收参数)
           FROM dbo.V_invoice WHERE 出仓日期<@date1 and 应收审核 ='Y' 
           GROUP BY 客户编号,出入单号           INSERT INTO @InvSs
           SELECT B.客户编号,C.送货单号,SUM(C.金额) 
           FROM dbo.Invoice_ysk B INNER JOIN dbo.Invoice_ysk_dt C 
                ON C.单号 = B.单号
           WHERE B.收款日期<@date1  
           GROUP BY B.客户编号,C.送货单号      
     COMMIT  TRANSACTION 
SELECT *
FROM @InvYs A LEFT JOIN @InvSs B ON B.出入单号 = A.出入单号
  RETURN 0   LB_ERROR:
        RAISERROR('发生错误,请检查输入!',16,1)
        ROLLBACK TRAN
        RETURN 100
END

解决方案 »

  1.   

    对,COMMIT  TRANSACTION 放前面去。
      

  2.   

    跟大江东去说的一样:COMMIT  TRANSACTION 放前面去。
      

  3.   

    我觉得commit transactin放在前后都是一样的。可能用临时表比较好,临时表也可以建索引。
      

  4.   

    当然是这句
    SELECT *
    FROM @InvYs A LEFT JOIN @InvSs B ON B.出入单号 = A.出入单号
      

  5.   

    SELECT top 100 *
    FROM @InvYs A LEFT JOIN @InvSs B ON B.出入单号 = A.出入单号
    看看结果和语句有没有不对的地方。
      

  6.   

    经我测试有很明显的区别。(内存256M)
    表R(ID INT IDENTITY,A INT) 临时表:2秒
    create table  #a(id int,a int)
    create table #b(id int,a int)insert #a select top 20000 * from r
    insert #b select top 20000 * from r
    select * from #a A left join #b B on A.id=B.iddrop table #a,#b表变量:1分钟没完。
    declare @a table(id int,a int)
    declare @b table(id int,a int)insert @a select top 20000 * from r
    insert @b select top 20000 * from r
    select * from @a A left join @b B on A.id=B.id你是不是硬盘快满了?
      

  7.   

    我现在改用实际表
    但我改了LEFT JOIN为INNER JOIN发现了区别
    用INNER JOIN 只要12秒
    用LEFT JOIN 要7分钟多第一次碰到这样的问题
      

  8.   

    left join与inner join的执行机制不一样。
      

  9.   

    --下面是例子:--如下测试表,实现随机排序,要求,name相同的排序在一齐,但name的顺序也是要排序的
    declare @t table(id int identity(1,1),name varchar(1))
    insert into @t(name)
    select 'a'
    union all select 'b'
    union all select 'b'
    union all select 'c'
    union all select 'a'--方法1.这个可以得到正确的结果
    select a.* from @t a left join(
    select aa=newid(),name from(select distinct name from @t) a
    ) b on a.name=b.name
    order by aa,newid()--方法2.这个不可以得到正确的结果
    select a.* from @t a join(
    select aa=newid(),name from(select distinct name from @t) a
    ) b on a.name=b.name
    order by aa,newid()
      

  10.   

    left join 和inner join的区别我自然懂了
    我只是奇怪为什么这两个连接方法速度会差别那么大?
      

  11.   

    看不出begin tran有什么用呢?用一句SQL不知道效率怎样: SELECT A.客户编号,A.最后出仓日期,A.出入单号,A.出入金额,
                    B.客户编号,B.送货单号,B.送货金额 
    FROM (SELECT min(客户编号) 客户编号,max(出仓日期) 最后出仓日期,
                 出入单号 单号,SUM(金额 * 应收参数) 出入金额 
                 FROM dbo.V_invoice WHERE 出仓日期<@date1 and 应收审核 ='Y' 
                 GROUP BY 出入单号 ) as A
             left join (SELECT min(B.客户编号) 客户编号,C.送货单号,
                   SUM(C.金额) as 送货金额
                 FROM dbo.Invoice_ysk B INNER JOIN dbo.Invoice_ysk_dt C 
                    ON C.单号 = B.单号 WHERE B.收款日期<@date1 
                 GROUP BY C.送货单号 ) as B
             on A.出入单号=B.送货单号
    这些字段应当有索引:出入单号、出仓日期、应收审核、单号、单号、收款日期、送货单号。
      

  12.   

    a left join b on a.key=b.key
    那么,在a.key上建立索引没用,因该只能用到b.key上的索引,这规定了查询规划只能把b放在“外层”。另外,table类型是可以建立索引的。例如:
    declare @t table(ID as char(6),Customer as char(15),salesQuantity float,
      primary key(ID,Customer))
      

  13.   

    如果我手工作优化,对于 a inner join b,如果a与b都没有索引,我把小的记录集合放在内层;对于都有合适的索引的情况,我则要反过来把大的集合放在内层;对于一个有索引一个没有索引,则把有索引的放在内层。但是,如果记录数小于1000条,则应该忽略索引;如果记录数很大并且字段上的值分布均匀适合建索引,则应该先自动建索引再查询然后再删除索引。总之,太复杂!还是在建立表结构时手工建立足够的索引,哪怕比需要的多一点。
      

  14.   

    我认为,到现在为止跟语句关系不大,他两表列数相当少.行数也就20000左右.
    改成临时表.在我的机上测可以快得多.
    我在我的机上一样的测试,相当快.应是你机器上的其它原因.
    索引和JOIN,也许会快些,不论怎么样也不会12秒和8分钟的区别.
    应在其它地方找原因.